
    ёic                   z   S SK Jr  S SKrS SKJrJrJr  S SKJr  S SK	r	S SK	J
r
  S SKJr  S SKJr  S SKJrJrJrJrJr  S S	KJrJrJrJr  S S
KJrJrJrJrJr  S SK J!r!  S SK"J#r#  S SK$J%r%J&r&J'r'J(r(J)r)J*r*J+r+J,r,  S8S jr- " S S5      r. " S S\.5      r/ " S S5      r0 " S S5      r1 " S S\.5      r2S r3 " S S5      r4\5\6\74r8S r9S r: " S S5      r;S9S  jr<S! r=S" r>S:S# jr?S:S$ jr@S% rAS& rBS' rCS( rD " S) S*5      rES;S+ jrFS, rGS- rHS. rIS/ rJS0 rKS1 rLS2 rMS3 rNS4 rO\         S<S5 j5       rP " S6 S75      rQg)=    )annotationsN)cached_propertypartialreduce)Any)_C_ops)core)_infer_var_data_type_shape_)OperatorProgramVariablein_pir_modestatic_only)build_assert_opbuild_if_opbuild_while_opcf_yield)LayerHelper
check_typecheck_variable_and_dtypeconvert_dtypein_dygraph_mode)use_pir_api)_PADDLE_PIR_DTYPE_2_NUMPY_DTYPE)assert_same_structurecopy_mutable_varsflattenhold_mutable_varsis_sequencemap_structurepack_sequence_asto_sequencec           	        [        U SS/S5        [        US[        [        [	        S5      4S5        [        US[
        S5        [        US[        [	        S5      4S5        [        5       (       a  Uc  / O
[        U5      n[        XU5      ngU(       a  UOSU R                  -   n[        U40 [        5       D6nUR                  S	Xc  / O
[        U5      S
.SU0S9nU$ )a  
This API creates an op that asserts the given condition is true. If the
condition is false, prints the tensors in data. ``summarize`` specifies the
number of the elements in the tensors to print.

Args:
    cond (Tensor): The boolean condition tensor whose numel should be 1.
    data (list|tuple, optional): list or tuple of tensors to print when
        condition is not true. If it's ``None``, no tensor will be printed.
        The default value is ``None``.
    summarize (int, optional): Number of elements in the tensor to be
        printed. If its value is -1, then all elements in the tensor will
        be printed. The default value is 20.
    name (str, optional): The default value is ``None`` . Normally users
        don't have to set this parameter. For more information, please
        refer to :ref:`api_guide_Name` .

Returns:
    Operator: the created operation.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.static.nn.control_flow import Assert

        >>> paddle.enable_static()
        >>> x = paddle.full([2, 3], 2.0, 'float32')
        >>> condition = paddle.max(x) < 1.0 # False
        >>> Assert(condition, [x], 10, "example_assert_layer")

        >>> exe = paddle.static.Executor()
        >>> try:
        ...     exe.run(paddle.static.default_main_program())
        ...     # Print x and throws ValueError
        ...     # Example printed message for x:
        ...     #
        ...     # Variable: fill_constant_0.tmp_0
        ...     #   - lod: {}
        ...     #   - place: CPUPlace()
        ...     #   - shape: [2, 3]
        ...     #   - layout: NCHW
        ...     #   - dtype: float
        ...     #   - data: [2 2 2 2 2 2]
        ... except ValueError as e:
        ...     print("Assert Exception Example")

condboolzstatic.nn.control_flow.AssertdataN	summarizenameassert_assert)CondData)typeinputsattrs)r   r   listtupler-   intstrr   r   r(   r   locals	append_op)	r$   r&   r'   r(   
input_data	assert_op
layer_namehelperops	            ]/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/static/nn/control_flow.pyAssertr<   ;   s    b fvh ? ftUDJ/1P y+s,KLtVc4:.0OP}}<RT$Z
#Di@	I		$9J0vx0F			Lbd4jII& 
 
B I    c                  *    \ rS rSrSrS rS rS rSrg)
BlockGuard   zt
BlockGuard class.

BlockGuard class is used to create a sub-block in a program by
using the Python `with` keyword.
c                P    [        U[        5      (       d  [        S5      eXl        g )NzBlockGuard takes a program)
isinstancer   	TypeErrormain_program)selfrD   s     r;   __init__BlockGuard.__init__   s!    ,00899(r=   c                8    U R                   R                  5         g N)rD   _create_blockrE   s    r;   	__enter__BlockGuard.__enter__   s    '')r=   c                @    U R                   R                  5         Ub  ggNFT)rD   	_rollbackrE   exc_typeexc_valexc_tbs       r;   __exit__BlockGuard.__exit__   s     ##%r=   )rD   N)	__name__
__module____qualname____firstlineno____doc__rF   rL   rU   __static_attributes__ r=   r;   r?   r?      s    )
*r=   r?   c                  @   ^  \ rS rSrU 4S jrU 4S jrU 4S jrSrU =r$ )
WhileGuard   c                   > [        U[        5      (       d  [        S5      e[        5       (       d#  [        TU ]  UR                  R                  5        Xl        g )NzWhileGuard takes a while op)	rB   WhilerC   r   superrF   r9   rD   while_op)rE   rd   	__class__s     r;   rF   WhileGuard.__init__   s?    (E**9::}}GX__99: r=   c                  > [        5       (       aM  [        U R                  R                  / 5      R	                  5       U l        U R
                  R                  5       $ [        R                  U R                  l	        [        TU ]  5       $ rI   )r   r   rd   cond_varbodyblockrL   rb   IN_WHILE_BLOCKstatusrc   rE   re   s    r;   rL   WhileGuard.__enter__   s^    =='(>(>CHHJDJ::''))$33w ""r=   c                4  > [        5       (       a<  [        U R                  R                  /5        U R                  R                  XU5      $ Ub  g[        R                  U R                  l        U R                  R                  5         [        TU ]  XU5      $ NF)r   r   rd   rh   rj   rU   rb   AFTER_WHILE_BLOCKrl   	_completerc   rE   rR   rS   rT   re   s       r;   rU   WhileGuard.__exit__   ss    ==dmm,,-.::&&x&AA$66!w6::r=   )rj   rd   )	rW   rX   rY   rZ   rF   rL   rU   r\   __classcell__re   s   @r;   r_   r_      s    !#; ;r=   r_   c                  *    \ rS rSrSrS rS rS rSrg)If   a  
**If**

If is an operator that bind two blocks (true_block and false_block) to a specific condition,
According to the condition, the corresponding block will be executed.

Args:
    cond (Value): A value whose data type is bool controlling which block is executed.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.static.nn.control_flow import ConditionalBlock

        >>> label = paddle.rand([1])
        >>> limit = paddle.ones([1]) * 0.5
        >>> cond = paddle.less_than(x=label, y=limit)
        >>> if_op = If(cond)
        >>> with if_op.true_block():
        ...     pass
        >>> with if_op.false_block():
        ...     pass
c                &   [        U[        5      (       dM  [        USS/S5        [        S UR                  S5      S:w  a"  [        S[        UR                  5       S35      e[        U5      U l        U R                  R                  5       U l	        g )Nr$   r%   zstatic.nn.Ifc                
    X-  $ rI   r]   abs     r;   <lambda>If.__init__.<locals>.<lambda>   s    15r=      4condition expected shape as [1], but given shape as .)
rB   r0   r   r   shaperC   r   if_opr$   rh   )rE   r$   s     r;   rF   If.__init__   s|    $%%$T6F8^L($**a8A=J4PTPZPZK[J\\]^  !&


)r=   c                6    U R                   R                  5       $ rI   )r   
true_blockrK   s    r;   r   If.true_block   s    zz$$&&r=   c                6    U R                   R                  5       $ rI   )r   false_blockrK   s    r;   r   If.false_block   s    zz%%''r=   )rh   r   N)	rW   rX   rY   rZ   r[   rF   r   r   r\   r]   r=   r;   rx   rx      s    2*'(r=   rx   c                  :    \ rS rSrSrS
S jrS rS rS rS r	S	r
g)ConditionalBlock   aV  
**ConditionalBlock**

ConditionalBlock is an operator that bind a block to a specific condition,
if the condition matches, the corresponding block will be executed.

Args:
    inputs (Variable): bool conditions.
    is_scalar_condition (bool): whether the branch is controlled by a scalar.
    name(str): name of this ConditionalBlock.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.static.nn.control_flow import ConditionalBlock

        >>> label = paddle.rand([1])
        >>> limit = paddle.ones([1]) * 0.5
        >>> cond = paddle.less_than(x=label, y=limit)
        >>> image = paddle.ones([1])

        >>> true_image = image[cond]
        >>> true_cond = ConditionalBlock([true_image])

        >>> with true_cond.block():
        ...     pass
        >>> with false_cond.block():
        ...     pass
Nc                    Xl         [        5       (       a"  U(       a  [        U5      S:w  a  [        S5      eg U H  n[	        US[
        S5        M     X l        [        SUS9U l        g )Nr   zSFor ConditionalBlock Api,  Only support one input while is_scalar_condition is Trueinputr   conditional_blockr(   )	r.   r   lenrC   r   r   is_scalar_conditionr   r9   )rE   r.   r   r(   
each_inputs        r;   rF   ConditionalBlock.__init__  sa    =="s6{a'7i  $
:w:LM % $7 !"5DAr=   c                |    [        5       (       a#  [        U R                  5      R                  5       $ [	        U 5      $ rI   )r   rx   r.   r   ConditionalBlockGuardrK   s    r;   rj   ConditionalBlock.block  s+    ==dkk?--//$T**r=   c                   U R                   R                  R                  5       nU R                   R                  R                  UR                  5      n[        5       n[        5       n[        XX0R                   S9u  pCU Vs/ s H  oRR                  U5      PM     nn/ nU H.  nUR                  U5      n	U	(       d  M  UR                  U	5        M0     UR                  [        R                  R                  R                  S9n
UR                  SU R                   US.Xz/S.UU R"                  S.S9nU R%                  U5      (       a  U R'                  X!U5        g g s  snf )N)r9   r-   r   )r+   Input)OutScope)	sub_blockr   r-   r.   outputsr/   )r9   rD   current_blockrj   
parent_idxsetget_inputs_outputs_in_block_var_recursive_find_var_recursiveappend
create_varr	   VarDescVarTypeSTEP_SCOPESr5   r.   r   "need_append_conditional_block_gradappend_conditional_block_grad)rE   inside_blockparent_blockintermediateparams	each_name
param_listout_listinner_out_name	inner_var
step_scopeconditional_block_ops               r;   completeConditionalBlock.complete  sZ   {{//==?{{//55l6M6MNu:,{{ 
 EK
DJy''	2F 	 
 *N$88HIy	* +
 ",,%%11 - 

  ,55$# %|<)'+'?'?  6  
 22<@@..,@ A5
s   Ec                R    UR                   nUR                  nUS:g  =(       a    X#:g  $ )N)backward_block_idxidx)rE   r   grad_sub_block_idxinside_block_idxs       r;   r   3ConditionalBlock.need_append_conditional_block_gradB  s2    )<<'++
 "$O);)O	
r=   c                   UR                   nU R                  R                  R                  U5      n[	        5       n[	        5       nUR
                   H  n[        U[        5      (       d   eUR                   H3  n	UR                  U	5       H  n
X;  d  M
  UR                  U
5        M     M5     UR                   H,  nUR                  U5       H  nUR                  U5        M     M.     M     / nU H8  nUR                  U5      nU(       d  M  UR                  UR                  5        M:     [         R"                  " UR$                  [	        5       UR$                  /5      u  nn[         R&                  R)                  5       n[         R&                  R*                  R,                  nUR$                  R/                  5       nUR1                  US   5        UR3                  UU5        UR5                  SU5        UR7                  SU Vs/ s H  nUS-   PM
     sn5        [	        5       nUR9                  5        H  nUR$                  R;                  UR=                  5       5      (       d  U[         R>                  " 5       :X  a  ML  UR$                  RA                  UR=                  5       5        UR                  U5        UU;  d  M  M     URC                  UR$                  5        URE                  UR$                  5        UR9                  5        H  nUU;   d  M  [G        UU5        M     U R                  R                  RI                  5         gs  snf )aY  
Append op `conditional_block_grad` manually.
When `optimizer.minimize/append_backward` is called in Paddle control flow,
grad ops will be appended before appending op `conditional_block` so that
op `conditional_block_grad` can't be appended when calling
`optimizer.minimize/append_backward`. After appending op `conditional_block`,
`conditional_block_grad` is appended manually.

Args:
    parent_block (Block): The block that `conditional_block_op` belongs to.
    inside_block (Block): The sub block of `conditional_block_op`.
    conditional_block_op (Operator): The forward op conditional_block.
r   r   z
Input@GRADz@GRADN)%r   r9   rD   rj   r   opsrB   r   input_namesr   addoutput_namesoutputr   r   r(   r	   get_grad_op_descdescop_proto_and_checker_makerkOpRoleAttrNameOpRoleBackwardr5   	copy_from	_set_attr	set_input
set_outputoutput_arg_nameshas_var_recursiveencodeempty_var_namevarinfer_var_typeinfer_shaper
   _sync_with_cpp)rE   r   r   r   r   grad_sub_blockr   r   each_opinamein_var_nameonameout_var_namer   inner_input_namer   grad_op_descop_grad_to_varop_role_attr_namebackwardnew_op_descparamnew_varsgrad_var_nameargs                            r;   r   .ConditionalBlock.append_conditional_block_gradL  s   " *<<11778JKu%))Ggx0000 ,,#*==#7K"6

;/ $8 -
 !--$+NN5$9L $$\2 %: . * 
 &$889IJIy!!)..1 !'
 (,'<'< %%su~/B/B.C(
$n
 !;;KKM2299BB"''113l1o./:gz2
C
u57?
C	
 5(99;M##55m6J6J6LMM D$7$7$99##M$8$8$:;LL'N2 < 	"">#6#67 3 34//1Ch+C@ 2 	  //1/ Ds   M
)r9   r.   r   FN)rW   rX   rY   rZ   r[   rF   rj   r   r   r   r\   r]   r=   r;   r   r      s#    >B+
*X
L2r=   r   c                  D   ^  \ rS rSrSrU 4S jrU 4S jrU 4S jrSrU =r	$ )r   i  a+  
ConditionalBlockGuard is derived from BlockGuard. It is dedicated for
holding a ConditionalBlock, and helping users entering and exiting the
ConditionalBlock via Python's 'with' keyword. However, ConditionalBlockGuard
is generally an internal component of IfElse, users should not use it directly.
c                |   > [        US[        S5        [        TU ]  UR                  R
                  5        Xl        g )Nrj   r   )r   r   rc   rF   r9   rD   rj   )rE   rj   re   s     r;   rF   ConditionalBlockGuard.__init__  s/    5'#35LM223
r=   c                    > [         TU ]  5       $ rI   )rc   rL   rm   s    r;   rL   ConditionalBlockGuard.__enter__  s    w ""r=   c                X   > U R                   R                  5         [        TU ]  XU5      $ rI   )rj   r   rc   rU   rs   s       r;   rU   ConditionalBlockGuard.__exit__  s%    

w6::r=   )rj   )
rW   rX   rY   rZ   r[   rF   rL   rU   r\   ru   rv   s   @r;   r   r     s    
#; ;r=   r   c                   S nU R                    H  n[        U[        5      (       d   eUR                   HB  nUR	                  U5       H*  nXr;  d  M
  U" XW5      (       a  M  UR                  U5        M,     MD     UR                   H,  nUR                  U5       H  n	UR                  U	5        M     M.     M     [        5       n
UR                  R                  U R                  5      nU H  nUR                  U5      nSnU R                  U5      (       a  U R                  U5      nU(       a  MF  U(       d  MO  UR                  [         R"                  R$                  R&                  :X  d  M  U
R                  U5        M     X-
  nX4$ )a  
Find inputs and outputs in current control flow block.
:param current_block: Current control flow block.
:param inner_inputs: Input var name of ops in current block.
:param inner_outputs: Output var name of ops in current block.
:return: inner_inputs, inner_outputs
c                j    SS/0nU R                   U;   a  X R                      nU H
  nXA;   d  M
    g   g)Nshuffle_batchshuffle_batch_seedTFr   )r:   var_nameIGNORE_VAR_NAMES	var_namesr(   s        r;   is_ignore_vars3get_inputs_outputs_in_block.<locals>.is_ignore_vars  sD    
 ,.B-CD77&&(1I!# " r=   N)r   rB   r   r   r   r   r   r   r   rD   rj   r   r   has_varr   r-   r	   r   r   DENSE_TENSOR_ARRAY)r   inner_inputsinner_outputsr9   r   r:   r   r   r   r   remove_inner_inputsr   parent_block_varcurrent_block_vars                 r;   r   r     s[   " "h''''^^E!xx3N= = !$$[1	  / $ __E "		% 0!!,/ !1 %   %&&,,]-E-EFL#';;KH   -- - 1 1+ >  !!!&&||##667  ##K0 $  5L&&r=   c                  :    \ rS rSrSrSrSrSrSS jrS r	S	 r
S
rg)rb   i  a  
:api_attr: Static Graph

while loop control flow. Repeat while body until cond is False.

Note:
    A new OP :ref:`api_paddle_static_nn_while_loop` is highly recommended instead of ``While`` if the shape of parameter ``cond`` is [1].
    OP :ref:`api_paddle_static_nn_while_loop` is easier to use and is called with less code but does the same thing as ``While`` .

Notice:
    Local variables created in ``While`` are similar to that created in while of C++, and cannot be referenced externally.
    As a result, they cannot be obtained through ``fetch_list`` of ``Executor``. If you would like to access the variable
    out of ``while`` , PaddlePaddle provides ``assign`` API to assign local variables to external. Please refer to example
    code 2 or refer to `issue#22724 <https://github.com/PaddlePaddle/Paddle/issues/22724>`_.

Args:
    cond(Variable): A Tensor whose data type is bool controlling whether to continue looping.
    is_test(bool, optional): A flag indicating whether execution is in test phase. Default value is False.
    name(str, optional): The default value is None.  Normally there is no need for user to set this property.  For more information, please refer to :ref:`api_guide_Name` .

Examples:
    .. code-block:: python
        :name: example-1

        >>> import paddle
        >>> import numpy as np

        >>> paddle.enable_static()

        >>> i = paddle.full(shape=[1], dtype='int64', fill_value=0)           # loop counter

        >>> loop_len = paddle.full(shape=[1],dtype='int64', fill_value=10)    # loop length

        >>> cond = paddle.less_than(x=i, y=loop_len)
        >>> while_op = paddle.static.nn.control_flow.While(cond=cond)
        >>> with while_op.block():
        ...     i = paddle.increment(x=i, value=1)
        ...     paddle.assign(paddle.less_than(x=i, y=loop_len), output=cond)

        >>> exe = paddle.static.Executor(paddle.CPUPlace())
        >>> exe.run(paddle.static.default_startup_program())

        >>> res = exe.run(paddle.static.default_main_program(), feed={}, fetch_list=[i])
        >>> print(res)
        [array([10], dtype=int64)]

    .. code-block:: python
        :name: example-2

        >>> import paddle
        >>> import numpy as np

        >>> paddle.enable_static()

        >>> i = paddle.full(shape=[1], dtype='int64', fill_value=0)
        >>> loop_len = paddle.full(shape=[1], dtype='int64', fill_value=10)
        >>> one = paddle.full(shape=[1], dtype='float32', fill_value=1)
        >>> data = paddle.static.data(name='data', shape=[1], dtype='float32')
        >>> sums = paddle.full(shape=[1], dtype='float32', fill_value=0)  # Define the variable to be obtained outside of While, which name should be different from the variable inside the While to be obtained

        >>> cond = paddle.less_than(x=i, y=loop_len)
        >>> while_op = paddle.static.nn.control_flow.While(cond=cond)
        >>> with while_op.block():
        ...     sums_tensor = paddle.add(x=data, y=data)
        ...     paddle.assign(sums_tensor, sums)  # Update the value of sums_tensor defined in While to the sums which defined outside of While through layers.assign
        ...     i = paddle.increment(x=i, value=1)
        ...     data = paddle.add(x=data, y=one)
        ...     paddle.assign(paddle.less_than(x=i, y=loop_len), output=cond)

        >>> feed_data = np.ones(1).astype('float32')
        >>> exe = paddle.static.Executor(paddle.CPUPlace())
        >>> exe.run(paddle.static.default_startup_program())
        >>> res = exe.run(paddle.static.default_main_program(), feed={'data': feed_data}, fetch_list=sums)
        >>> print(res[0]) # Because the data in While does not update the value outside the While, the value of sums is [2.] after the loop
        [2.]
r   r      Nc                   Xl         [        USS/S5        [        S UR                  S5      S:w  a"  [	        S[        UR                  5       S35      e[        5       (       a  g [        R                  U l	        [        SUS	9U l        X l        g )
Nr$   r%   zstatic.nn.Whilec                
    X-  $ rI   r]   r|   s     r;   r    While.__init__.<locals>.<lambda>D  s    qur=   r   r   r   whiler   )rh   r   r   r   rC   r0   r   rb   BEFORE_WHILE_BLOCKrl   r   r9   is_test)rE   r$   r  r(   s       r;   rF   While.__init__A  s~     vx9JK$djj!49FtDJJGWFXXYZ  ==..!'5r=   c                    [        U 5      $ rI   )r_   rK   s    r;   rj   While.blockN  s    $r=   c           	        U R                   R                  nUR                  5       nUR                  UR                  5       R                  5      nU R
                  R                  1n[        5       n[        X%X@R                   5      u  pT/ nU H.  nUR                  U5      nU(       d  M  UR                  U5        M0     XV V	s1 s H  oR                  iM     sn	-  nXPR
                  R                  1-  nUR                  [        R                  R                  R                  S9n
UR!                  SU Vs/ s H  nUR#                  U5      PM     snU R
                  /S.Xj/S.X R$                  S.S9  g s  sn	f s  snf )Nr   r
  )X	Condition)r   
StepScopes)r   r  r   )r9   rD   r   rj   r   rh   r(   r   r   r   r   r   r	   r   r   r   r5   r   r  )rE   rD   while_blockr   r  x_name_listout_varsr   r   xr   x_names               r;   rr   While._completeQ  sn   {{//"002#))&&(33
 ++,e%@m[[&
" +N$88HIy	* ,
 	1111 	**++!,,%%11 - 

 	 #."- !//7"- #mm_ %LA +E 	 	
 2s   E77E<
)rh   r9   r  rl   r   )rW   rX   rY   rZ   r[   r  rk   rq   rF   rj   rr   r\   r]   r=   r;   rb   rb     s+    KZ N '
r=   rb   c                   S n[        U [        [        R                  R                  45      (       dD  [        U[        5      (       a,  [        U [
        5      (       a  [        R                  " X5        gU ngU R                  [        R                  R                  R                  :X  a  U R                  R                  nUR                  UR                  5       R                  5      nU(       a8  UR!                  U R"                  5      (       d  [        R                  " X5        ggg[        U[        5      (       aS  [        U [        5      (       a>  U" X5      (       a1  [$        R&                  " SU R(                   SUR(                   S35        [        R*                  R,                  R/                  5          [        R                  " X5        SSS5        g! , (       d  f       g= f)zn
Assign input to output, but skip the process of copying DenseTensorArray unless it's created in while_block.
c                    [        U R                  5      [        UR                  5      :w  a  g[        U R                  UR                  5       H  u  p#X#:w  d  M  SX#4;  d  M    g   g)NTr   F)r   r   zip)x_vary_varx_dimy_dims       r;   has_shape_diff4assign_skip_lod_tensor_array.<locals>.has_shape_diff  sP    u{{s5;;//U[[9LE~"UN": : r=   Nz>In dy2static mode, we attempt to assign a variable with shape z into a variable with shapez, which is not always right.)rB   r   r	   eagerTensorsupport_ret_buildin_typepaddleassignr-   r   r   r   rj   programr   r   r   r(   warningswarnr   base	framework_stride_in_no_check_dy2st_diff)r   r   r!  rD   r   s        r;   assign_skip_lod_tensor_arrayr.  ~  sv   
 eh

(9(9:;;fh''J+-
 -
 MM%( 	 FzzT\\))<<<{{**#))&&(33
  @ @ L LMM%( !M< vx((5(++u--MMPQVQ\Q\P]]xy  zF  zF  yG  Gc  d [[""AACMM%( DCCs   8G
G&c                   UR                   n[        R                  " / UR                  SS9nUR	                  5       nUR                  U R                  5       5        UR                  UR                  5       5        X#l         U R                  U5        U R                  5       R                  UR                  5       5      nX%l         X54$ )Nr   r   dtype
fill_value)stop_gradientr&  fullr1  get_defining_opmove_beforeas_operationset_typer-   add_extra_inputri   add_arg)rd   valuer3  
fake_valuefake_value_op	block_args         r;   #create_fake_value_for_undefined_varr?    s    ''M2U[[QGJ..0Mh3356

%,Z(''

5I+  r=   c                  v    \ rS rSrSS jr\S 5       r\S 5       r\S 5       r\S 5       r	S r
S	 rS
 rS rSrg)LoopVari  Nc                6    Xl         X l        X0l        SU l        g rp   )curr_varnext_varr>  _is_fake)rE   rC  rD  r>  s       r;   rF   LoopVar.__init__  s      "r=   c                ^    [        U R                  [        R                  R                  5      $ rI   )rB   rC  r&  pirValuerK   s    r;   is_variable_curr_varLoopVar.is_variable_curr_var      $--)9)9::r=   c                    [        U R                  [        R                  R                  R
                  R                  5      $ rI   )rB   rC  r&  jit	dy2staticutilsUndefinedVarrK   s    r;   is_undefined_curr_varLoopVar.is_undefined_curr_var  s.    MM6:://55BB
 	
r=   c                ^    [        U R                  [        R                  R                  5      $ rI   )rB   rD  r&  rH  rI  rK   s    r;   is_variable_next_varLoopVar.is_variable_next_var  rL  r=   c                    U R                   $ rI   )rE  rK   s    r;   is_fakeLoopVar.is_fake  s    }}r=   c                    Xl         g rI   )r>  )rE   r>  s     r;   bind_block_argLoopVar.bind_block_arg  s    "r=   c                    Xl         g rI   rD  )rE   rD  s     r;   bind_next_varLoopVar.bind_next_var  s     r=   c                  ^ ^ T R                   (       d   eS n[        U[        R                  R                  5      (       a	  U" TU5      $ [        U5      (       a  [        U U4S jU5      $ [        T R                  UT R                  5      $ )Nc                F    [        X5      u  p#[        X!U5      nSUl        U$ )NT)r?  rA  rE  )rd   rD  r<  r>  loop_vars        r;   create_loop_var_like>LoopVar.infer_type_with_next_var.<locals>.create_loop_var_like  s-    $G%!J zY?H $HOr=   c                (   > TR                  U T5      $ rI   )infer_type_with_next_var)r   rE   rd   s    r;   r   2LoopVar.infer_type_with_next_var.<locals>.<lambda>  s    D99#xHr=   )
rR  rB   r&  rH  rI  r   r    rA  rC  r>  )rE   rD  rd   rd  s   ` ` r;   rg   LoopVar.infer_type_with_next_var  st    ))))	 h

 0 011'(;;x   H  t}}h??r=   c                V    SU R                    SU R                   SU R                   S3$ )NzLoopVar(curr_var=z, next_var=z, block_arg=))rC  rD  r>  rK   s    r;   __repr__LoopVar.__repr__  s.    "4==/T]]O<X\XfXfWgghiir=   )rE  r>  rC  rD  NN)rW   rX   rY   rZ   rF   propertyrJ  rR  rU  rX  r[  r_  rg  rl  r\   r]   r=   r;   rA  rA    sm     ; ; 
 

 ; ;  #!@(jr=   rA  c           
     b
  ^^ [        U 5      (       d  [        S5      e[        U5      (       d  [        S5      e[        US[        [        4S5        [        U5      S:X  a  [        S5      eU " U6 n[        USS/S5        [        S	 UR                  S
5      S
:w  a"  [        S[        UR                  5       S35      e[        5       (       Ga  S n[        [        U5      n[        U5       Vs/ s H  nUR                  (       d  M  UPM     nn[        XX V	s/ s H  oR                   PM     sn	5      mTR#                  5        n
[        U
R%                  5       5      [        U5      :X  d   e['        XR%                  5       5       H$  u  p{UR)                  UR+                  5       5        M&     [        S U5      nU" U6 n[-        U[        [        45      (       d  U/nU4S jn [/        UUSS S9  U" X-5      nSSKJm  U4S jn[4        R6                  R                  UU5        U " [        S U5      6 nSUl        [        Xb5        [        [;        S [        U5      5      5      [        [;        S [        U5      5      5      -   n[=        U/S U 5       Q5        SSS5        TR?                  5       n[        U5      [        U5      :X  d   e['        UU5       H  u  nnUUl         M     [        U5       Hp  nURB                  (       d  M  UR                   RE                  5       (       d  M7  UR                   RG                  5       nURI                  5       RK                  U5        Mr     [        S U5      $ [M        5       (       a  URO                  5       nU(       as  U" U6 n[-        U[        [        45      (       d  U/n[        U5      [        U5      :w  a  [        S5      eU " U6 RO                  5       n[        [P        UU5        U(       a  Ms  U$ [S        XSU5      n[U        U5      nURW                  5          U(       a  [Y        U5      nU" U6 nOU" U6 n[-        U[        [        45      (       d  U/n [[        UU5      n[/        UUSS9  U " U6 n[        [P        UU5        [4        R\                  " UU5        SSS5        U$ s  snf s  sn	f ! [         a  n[        SU 35      eSnAff = f! , (       d  f       GNY= f! [         a  n[        SU 35      eSnAff = f! , (       d  f       U$ = f)a}  
:api_attr: Static Graph

while_loop is one of the control flows. Repeats while_loop `body` until `cond` returns False.

Notice:
    Local variables defined in ``body`` cannot be obtained through ``fetch_list`` of ``Executor`` , variables should
    be defined outside ``body`` and placed in ``loop_vars`` for looping, then these variables can be fetched by ``fetch_list`` .

Args:
    cond(Callable): A callable returning a boolean tensor controlling whether to continue looping. And ``cond`` takes
        as many arguments as ``loop_vars`` .
    body(Callable): A callable returning a tuple or list of tensors or DenseTensorArrays of the same arity
        (length and structure) and types as ``loops_vars`` . And ``body`` takes as many arguments as ``loop_vars`` .
    loop_vars(list|tuple): A list or tuple of tensors or DenseTensorArrays that is passed to both ``cond`` and ``body`` .
    is_test(bool, optional): A flag indicating whether execution is in test phase. Default value is False.
    name(str, optional): Normally there is no need for users to set this property. For more information, please
        refer to :ref:`api_guide_Name`. Default is None.

Returns:
    A list or tuple of Tensors or DenseTensorArrays which returned by ``body`` .

Examples:
    .. code-block:: python

        >>> import paddle
        >>> paddle.enable_static()

        >>> def cond(i, ten):
        ...     return i < ten

        >>> def body(i, ten):
        ...     i = i + 1
        ...     return [i, ten]

        >>> main_program = paddle.static.default_main_program()
        >>> startup_program = paddle.static.default_startup_program()
        >>> with paddle.static.program_guard(main_program, startup_program):
        ...     i = paddle.full(shape=[1], fill_value=0, dtype='int64')     # loop counter
        ...     ten = paddle.full(shape=[1], fill_value=10, dtype='int64')  # loop length
        ...     i, ten = paddle.static.nn.while_loop(cond, body, [i, ten])

        ...     exe = paddle.static.Executor(paddle.CPUPlace())
        ...     res = exe.run(main_program, feed={}, fetch_list=[i])
        ...     print(res)
        [array([10], dtype=int64)]
z%cond in while_loop should be callablez%body in while_loop should be callable	loop_varszstatic.nn.while_loopr   z+loop_vars in while_loop should not be emptyzvar of cond returnedr%   c                
    X-  $ rI   r]   r|   s     r;   r   while_loop.<locals>.<lambda>0  s    15r=   r   zLthe shape of the variable returned by cond should be [1],but given shape as r   c                   [         R                  " 5       nUR                  n[         R                  R                  [         R                  R
                  /nX#;  a  g U R                  (       d  g U R                  R                  U R                  R                  :w  a<  [        R                  " U R                  U R                  R                  5      nX@l	        g g rI   )r	   _get_amp_attrs
_amp_levelAmpLevelO1O2rJ  rC  r1  rD  r&  cast)rc  	amp_attrs	amp_levelapply_amp_level_listcast_out_vars        r;   cast_value_in_amp%while_loop.<locals>.cast_value_in_amp8  s    ++-I!,,I    $  400  &&(*;*;*A*AA%{{%%x'8'8'>'>  %1!	 Br=   c                T    U R                   (       a  U R                  $ U R                  $ rI   )rJ  r>  rC  r   s    r;   r   rs  Y  s    %(%=%=CMMO3<<Or=   c                r   >^ UU4S jm/ n[        X5       H  u  p4UR                  T" XC5      5        M     U$ )Nc                   > [        U 5      (       a  [        TU U5      $ U R                  (       a  U R                  UT5      nU$ U R	                  U5        U nU$ rI   )r   r    rR  rg  r_  )rc  rD  new_loop_var!infer_loop_var_type_with_next_varrd   s      r;   r  bwhile_loop.<locals>.infer_loop_vars_type_with_next_vars.<locals>.infer_loop_var_type_with_next_vard  sg    "8,,,=$$  
  55'/'H'H$h( (' !..x8'/''r=   )r  r   )rq  	next_varsnew_loop_varsrD  rc  r  rd   s        @r;   #infer_loop_vars_type_with_next_vars7while_loop.<locals>.infer_loop_vars_type_with_next_varsc  s@    (  !#*-i*C&H!((9(M +D %$r=   Fc                2   [        U [        5      =(       aB    [        U R                  [        R                  R
                  R                  R                  5      =(       d8    [        U [        R                  R
                  R                  R                  5      $ rI   )rB   rA  rC  r&  rN  rO  rP  rQ  r  s    r;   r   rs    sf    "1g. &JJ

(<(<(B(B(O(O'P #1fjj&:&:&@&@&M&MN'Pr=   )check_typesskip_ifzUbody in while_loop should return the same arity (length and structure) as loop_vars: Nto_static_variablec                (  > U R                   (       d  g [        U R                  [        R                  R
                  5      (       d5  [        U R                  [        [        [        45      (       d  [        S5      eT" U R                  5      U l        g )NzThe loop var in the while op is variable, but the corresponding yielded var is not variable, and it is not a constant of type bool, int, or float.)
rJ  rB   rD  r&  rH  rI  r%   floatr2   
ValueError)rc  r  s    r;   check_next_var"while_loop.<locals>.check_next_var  ss    44!%%vzz'7'7 $X%6%6uc8JKK$ m  %7x7H7H$I!r=   c                    U R                   $ rI   r^  r  s    r;   r   rs    s    3<<r=   Tc                J    U R                   =(       a    U R                  (       + $ rI   rJ  rX  r  s    r;   r   rs    s     8 8 L_ Lr=   c                @    U R                   =(       a    U R                  $ rI   r  r  s    r;   r   rs    s     8 8 HS[[ Hr=   c              3  8   #    U  H  oR                   v   M     g 7frI   r^  ).0r   s     r;   	<genexpr>while_loop.<locals>.<genexpr>  s     "N;MC<<;M   c                    U R                   $ rI   r^  r  s    r;   r   rs    s    r=   z]body in while_loop should return the same arity (length and structure) and types as loop_varsr  )/callablerC   r   r0   r1   r   r  r   r   r   r   r    rA  r   rJ  r   rC  ri   argsr  r[  _clonerB   r   &paddle.jit.dy2static.convert_operatorsr  r&  rP  r3  filterr   optimize_updaterD  rX  	use_emptyr5  get_parent_block	remove_opr   itemr.  rb   r   rj   r   _deal_with_undefined_varr'  )r$   ri   rq  r  r(   pre_condr  rc  variable_loop_varsr   	cur_blockr   r  r  r  er  	next_condoptimized_resultsresultfake_value_def_opnow_condoutput_varswhile_loop_blockhas_mutable_vars_in_loopr  r  rd   s                             @@r;   
while_loopr    s   ` D>>?@@D>>?@@y+e}6LM
9~FGGYH(6(4J  (..!49""&x~~"6!7q:
 	

 }}	1" 'w	:	 $I.
.,, . 	 

 "/AB/A||/AB
 ]]_	y~~'(C0B,CCCC!$%79I!J''

5 "K ! 	D dIi$77&K	%0% %P	$ <I	J LL&&~yA7CI '+I# +7!%LI&"
 HI&
" iO"N;M"NOPK P %446$%-?)@@@@ #$68I JHf &H !K  	*HH$5$5$?$?$A$A$,$5$5$E$E$G!!224>>% + $
 	

 ==?	*KkD%=99*m;3y>1 D  [)..0H6YO h X50;				!
 $-i8M.K	*K+e}55&-K	0iHI!+yeL %2KKh)- 
". U
 Cp   <<=3@ m _t  	889s< 	 
"	!. st   -SSS
B S-$S1B*S-8<T5S?-T
S*S%%S**S--
S<?
T	TTT
T.c                  ^ SSK JnJm  U4S jn[        U 5      [        U5      :w  a  [	        S5      e/ n[        X5       HB  u  pV[        Xb5      (       d  Uc  UR                  U" U5      5        M1  UR                  U5        MD     U$ )a  Deal with undefined var cases, We create undefined variable based on the results of body().
In Dy2Static, we use undefined var to represent the var created in control flow. This function
expand the loop_vars and replace original loop_vars.
1. UndefinedVar = Variable      # create a variable
2. UndefinedVar = None          # create a undefined var with RETURN_NO_VALUE_MAGIC_NUM
3. UndefinedVar = List(int)     # create a list of variable
4. UndefinedVar = value         # create a variable
r   )rQ  create_undefined_variablec                   > [        U [        /[        Q75      (       d  U c  T" 5       $ [        U 5      (       a   [	        U4S jU 5      $ g )Nc                   > T" 5       $ rI   r]   )r  r  s    r;   r   C_deal_with_undefined_var.<locals>.create_var_like.<locals>.<lambda>  s	    +D+Fr=   )rB   r   r%  r   r    )o_varr  s    r;   create_var_like1_deal_with_undefined_var.<locals>.create_var_like  sL    uxC*BCDD},..u !!FNN	 r=   z+The length of loop_vars should be the same.)paddle.jit.dy2static.utilsrQ  r  r   r  r  rB   r   )r  rq  rQ  r  resultsr  l_varr  s          @r;   r  r    sv    

O ;3y>)FGGGK3e**emNN?512NN5!	 4
 Nr=   c           
     (    U  SU SU SU SU S3
nU$ )Nz of 'z' in z	 must be z, but received: r   r]   )whatarg_nameop_nameright_valueerror_valueerror_messages         r;   _error_messager    s5    &hZuWIY-'}A	7 
 r=   c                x    S nU" X5      u  pUn[        U 5       H  u  pV[        [        XVUS9nM     UnU" 5       $ )a  
:api_attr: Static Graph

This operator works like an if-elif-elif-else chain.

Args:
    pred_fn_pairs(list|tuple): A list or tuple of (pred, fn) pairs. ``pred`` is a boolean Tensor whose numel should be 1 (shape [] or shape [1]), ``fn`` is a callable. All callables return the same structure of Tensors.
    default(callable, optional): Callable that returns a structure of Tensors.
    name(str, optional): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`.

Returns:
    Tensor|list(Tensor): Tensors returned by the callable from the first pair whose pred is True,
    or Tensors returned by ``default`` if no pred in ``pred_fn_pairs`` is True and ``default`` is not None,
    or Tensors returned by the last callable in ``pred_fn_pairs``  if no pred in ``pred_fn_pairs`` is True and ``default`` is None.

Raises:
    TypeError: If the type of ``pred_fn_pairs`` is not list or tuple.
    TypeError: If the type of elements in ``pred_fn_pairs`` is not tuple.
    TypeError: If the size of tuples in ``pred_fn_pairs`` is not 2.
    TypeError: If the first element of 2-tuple in ``pred_fn_pairs`` is not a Tensor.
    TypeError: If the second element of 2-tuple in ``pred_fn_pairs`` is not callable.
    TypeError: If ``default`` is not None but it is not callable.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> paddle.enable_static()

        >>> def fn_1():
        ...     return paddle.full(shape=[1, 2], dtype='float32', fill_value=1)

        >>> def fn_2():
        ...     return paddle.full(shape=[2, 2], dtype='int32', fill_value=2)

        >>> def fn_3():
        ...     return paddle.full(shape=[3], dtype='int32', fill_value=3)

        >>> main_program = paddle.static.default_startup_program()
        >>> startup_program = paddle.static.default_main_program()

        >>> with paddle.static.program_guard(main_program, startup_program):
        ...     x = paddle.full(shape=[1], dtype='float32', fill_value=0.3)
        ...     y = paddle.full(shape=[1], dtype='float32', fill_value=0.1)
        ...     z = paddle.full(shape=[1], dtype='float32', fill_value=0.2)

        ...     pred_1 = paddle.less_than(z, x)  # true: 0.2 < 0.3
        ...     pred_2 = paddle.less_than(x, y)  # false: 0.3 < 0.1
        ...     pred_3 = paddle.equal(x, y)      # false: 0.3 == 0.1

        ...     # Call fn_1 because pred_1 is True
        ...     out_1 = paddle.static.nn.case(
        ...         pred_fn_pairs=[(pred_1, fn_1), (pred_2, fn_2)], default=fn_3)

        ...     # Argument default is None and no pred in pred_fn_pairs is True. fn_3 will be called.
        ...     # because fn_3 is the last callable in pred_fn_pairs.
        ...     out_2 = paddle.static.nn.case(pred_fn_pairs=[(pred_2, fn_2), (pred_3, fn_3)])

        ...     exe = paddle.static.Executor(paddle.CPUPlace())
        ...     res_1, res_2 = exe.run(main_program, fetch_list=[out_1, out_2])
        ...     print(res_1, res_2)
        [[1. 1.]] [3 3 3]
c                   [        U S[        [        4S5        U  H  n[        U[        5      (       d%  [	        [        SSS[        [        U5      5      5      e[        U5      S:w  a-  [	        [        SSSS[        [        U5      5      S-   5      5      eUu  p4[        USS	/S
5        [        U5      (       a  M  [	        S5      e   Uc  [        U 5      S-
  nX   S   nU SU n X4$ [        U5      (       d  [	        S5      eX4$ )zW
Check arguments pred_fn_pairs and default. Return canonical pre_fn_pairs and default.
pred_fn_pairscaseThe elements' typer  The tuple's size2-tuplepredr%   zpaddle.static.nn.casez5The fn of pred_fn_pairs in Op(case) must be callable.Nr   )The default in Op(case) must be callable.)r   r0   r1   rB   rC   r  r-   r   r3   r   r  )r  defaultpred_fnr  fndefault_indexs         r;   _case_check_argscase.<locals>._case_check_argsg  s*    	=/D%=&I$Ggu--",'W  7|q "*'CL)H4  HD$fvh(? B<<K 9 %@ ?.2M#215G).=9M %% '""GHH%%r=   r  true_fnfalse_fn)reversedr   r$   )r  r  r(   r  r  r  r  final_fns           r;   r  r  &  sK    B-&^ .mEMH!-04dhO 1 H:r=   c                    [        S0 [        5       D6nS nU" XU5      u  pbUnU H  u  p[        [        XUS9nM     Un
U
" 5       $ )a  
:api_attr: Static Graph

This operator is like a C++ switch/case statement.

Args:
    branch_index(Tensor): A Tensor whose numel should be 1 (shape [] or shape [1]) to specify which branch to execute. The data type is ``int32``, ``int64`` or ``uint8``.
    branch_fns(dict|list|tuple): If it's a list or tuple, the elements in it could be pairs of (int, callable) or simple callables whose actual index will be used as the index of callable. If it's a dict, its key is a python integer and the value is a callable. All callables return the same structure of Tensors.
    default(callable, optional): Callable that returns a structure of Tensors.
    name(str, optional): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`.

Returns:
    Tensor|list(Tensor): Tensors returned by the callable specified by ``branch_index`` in ``branch_fns``,
    or Tensors returned by ``default`` if ``default`` is not None and no index matches in ``branch_fns``,
    or Tensors returned by the callable with the max index in ``branch_fns`` if ``default`` is None and no index matches in ``branch_fns``.

Raises:
    TypeError: If the type of ``branch_index`` is not Tensor.
    TypeError: If the data type of ``branch_index`` is not ``int32``, ``int64`` or ``uint8``.
    TypeError: If the type of ``branch_fns`` is not dict, list or tuple.
    TypeError: If the elements of ``branch_fns`` is not 2-tuple.
    TypeError: If the first element of 2-tuple in ``branch_fns`` is not integer.
    ValueError: If the first element of 2-tuple in ``branch_fns`` is not unique.
    TypeError: If the second element of 2-tuple in ``branch_fns`` is not callable.
    TypeError: If ``default`` is not None but it is not callable.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> paddle.enable_static()

        >>> def fn_1():
        ...    return paddle.full(shape=[1, 2], dtype='float32', fill_value=1)

        >>> def fn_2():
        ...    return paddle.full(shape=[2, 2], dtype='int32', fill_value=2)

        >>> def fn_3():
        ...    return paddle.full(shape=[3], dtype='int32', fill_value=3)

        >>> startup_program = paddle.static.default_startup_program()
        >>> main_program = paddle.static.default_main_program()
        >>> with paddle.static.program_guard(main_program, startup_program):
        ...    index_1 = paddle.full(shape=[1], dtype='int32', fill_value=1)
        ...    index_2 = paddle.full(shape=[1], dtype='int32', fill_value=2)
        ...
        ...    out_1 = paddle.static.nn.switch_case(
        ...        branch_index=index_1,
        ...        branch_fns={1: fn_1, 2: fn_2},
        ...        default=fn_3)
        ...
        ...    out_2 = paddle.static.nn.switch_case(
        ...        branch_index=index_2,
        ...        branch_fns=[(1, fn_1), (2, fn_2)],
        ...        default=fn_3)
        ...
        ...    # Argument default is None and no index matches. fn_3 will be called because of the max index 7.
        ...    out_3 = paddle.static.nn.switch_case(
        ...        branch_index=index_2,
        ...        branch_fns=[(0, fn_1), (4, fn_2), (7, fn_3)])
        ...
        ...    exe = paddle.static.Executor(paddle.CPUPlace())
        ...    res_1, res_2, res_3 = exe.run(main_program, fetch_list=[out_1, out_2, out_3])
        ...    # Variable: fill_constant_1.tmp_0
        ...    #   - message: The content of input layer:
        ...    #   - lod: {}
        ...    #   - place: Place(cpu)
        ...    #   - shape: [2, 3]
        ...    #   - layout: NCHW
        ...    #   - dtype: int64
        ...    #   - data: [3 3 3 3 3 3]

        >>> print(res_1)
        [[1. 1.]]

        >>> print(res_2)
        [[2 2]
         [2 2]]

        >>> print(res_3)
        [3 3 3]
c                   [        U S/ SQS5        [        U R                  5      S:w  a  [        R                  " U S5      n [        US[        [        [        4S5        [        U[        5      (       a  UR                  5       OUn[        S U 5       5      (       a  [        [        U5      5      OUn/ nU GH  n[        U[        5      (       d%  [        [        SSS[        [        U5      5      5      e[!        U5      S	:w  a-  [        [        S
SSS[#        [!        U5      5      S-   5      5      eUu  pV[        U[$        5      (       d%  [        [        SSS[$        [        U5      5      5      eXS;   a  ['        SU S35      eUR)                  U5        [+        U5      (       a  M  [        [        SU 3SSS[        U5      5      5      e   Uc   [-        U5      S   S   n[-        U5      S S nO[+        U5      (       d  [        S5      e/ nU HD  u  p[        R.                  " S/SUS9n	[        R0                  " X	5      n
UR)                  X45        MF     Xr4$ )Nbranch_index)uint8int32int64zstatic.nn.switch_caser  
branch_fnsswitch_casec              3  8   #    U  H  n[        U5      v   M     g 7frI   )r  )r  r  s     r;   r  3switch_case.<locals>._check_args.<locals>.<genexpr>
  s     5*B8B<<*r  r  r  r  r  r  zThe key's typez-The key in 'branch_fns' must be unique, but 'z' appears more than once.zThe type of function for key r  r   r   r  r0  )r   r   r1  r&  rz  r   r0   r1   dictrB   itemsall	enumeraterC   r  r-   r   r3   r2   r  r   r  sortedr4  equal)r  r  r  keys_of_fnsindex_fn_pairkeyr  r  index	new_indexr  s              r;   _check_args switch_case.<locals>._check_args  s_    '#		
 ++,7!;;|W=L:|dE4-@-P #-Z">">JJ 	 5*555 :&' 	 'MmU33",$%Z(  =!Q&"*$%C./(:  $GCc3''"($%S	  ! CC5Hab  ""3'B<<"7u=$%"R Y (l ?Z(,Q/G
+CR0J'""GHH#IE1#WOI<<8D  $, $
 %%r=   r  )r  )r   r4   r   r$   )r  r  r  r(   r9   r  r  r  r  r  r  s              r;   r  r    sZ    h 3&(3FZ&x )7KMH&4dhO ' H:r=   c                   [        [        U5      S-   5       Vs/ s H  n/ PM     nn[        U 5       HP  u  pE[        U5       H(  u  pgU" U5      (       d  M  X6   R                  U5          M:     US   R                  U5        MR     U$ s  snf )Nr   r   ranger   r  r   )	containerdiscriminators_bucketsr   r  ir$   s           r;   get_indices_by_discriminatorr  \  s     ^!4q!89:9ar9G:y)	 0GADzz
!!#& 1
 BKs# * N ;s   B	c                    [        [        U5      5       Vs/ s H  n/ PM     nn[        U 5       H4  u  pE[        U5       H   u  pgXG;   d  M  X6   R                  U5          M2     M6     U$ s  snf rI   r  )r  index_groupsr  r  r   r  r   indicess           r;   select_by_indicesr  h  sh     \!2343ar3G4y)	#L1JA~
!!$' 2 *
 N 5s   A*c                     [        S U S5      n[        U5       Vs/ s H  nS PM     nnU  H7  u  pE[        U5      [        U5      :X  d   e[        XT5       H	  u  pgXsU'   M     M9     U$ s  snf )Nc                $    U [        US   5      -   $ Nr   )r   )accpairs     r;   r   7create_container_by_items_and_indices.<locals>.<lambda>t  s    #DG,r=   r   )r   r  r   r  )items_indices_pairstotal_lengthr  r  partial_containerr  r   r  s           r;   %create_container_by_items_and_indicesr  r  s|    ,.A1L  %\232!2I3&9"$%W555W8IC!cN 9 ':  4s   A)c                   ^ ^ UU 4S jnU$ )Nc                 X   > T" 5          T" U 0 UD6sS S S 5        $ ! , (       d  f       g = frI   r]   )r  kwargsrj   r  s     r;   new_fnrun_with_block.<locals>.new_fn  s    Wt&v& WWs   
)r]   )r  rj   r  s   `` r;   run_with_blockr  ~  s    ' Mr=   c                      \ rS rSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       rS rS	 r\S
 5       r\S 5       rSrg)OutputSelectori  c                    Xl         X l        X0l        X@l        [	        U5      U l        [	        U5      U R
                  :X  d   e[	        U5      U R
                  :X  d   eg rI   )r   true_outputfalse_outputnamesr   
num_output)rE   r   flattened_true_outputflattened_false_outputr  s        r;   rF   OutputSelector.__init__  sU     
02
34)*doo===5zT__,,,r=   c                   / n/ n[        U R                  U R                  U R                  5       H  u  p4n[        R                  X0R                  R                  4X@R                  R                  4/U5      u  nn[        R                  X0R                  R                  4X@R                  R                  4/U5      u  p4UR                  U5        UR                  U5        M     X4$ rI   )r  r  r  r  r  constant_to_variable_promotionr   r   r   precision_promotionr   )rE   unified_true_outputunified_false_outputtrue_out	false_outr(   s         r;   unified_outputOutputSelector.unified_output  s     !),d//*
%H ==zz445

 6 67  %3$F$Fzz445

 6 67 %!X  &&x0 ''	2+*
, #88r=   c                     U R                   S   $ r  r'  rK   s    r;   r#  "OutputSelector.unified_true_output      ""1%%r=   c                     U R                   S   $ )Nr   r*  rK   s    r;   r$  #OutputSelector.unified_false_output  r,  r=   c                    [        U R                  S 5      u  p[        U R                  S 5      u  p2X:X  d   S5       eU$ )Nc                J    [        U [        R                  R                  5      $ rI   rB   r&  rH  rI  r  s    r;   r   1OutputSelector.variable_indices.<locals>.<lambda>      jFJJ$4$45r=   c                J    [        U [        R                  R                  5      $ rI   r1  r  s    r;   r   r2    r3  r=   z?true_variable_indices and false_variable_indices should be same)r  r#  r$  )rE   true_variable_indicesr  false_variable_indicess       r;   variable_indicesOutputSelector.variable_indices  sY    #?$$5$
  %A%%5%
! %> 	
M	
> %$r=   c                    [        [        U R                  5      5       Vs/ s H  nXR                  ;  d  M  UPM     sn$ s  snf rI   )r  r   r  r7  )rE   r   s     r;   constant_indicesOutputSelector.constant_indices  sE     3t//01
1--- 1
 	
 
s
   AAc                    [        U R                  U R                  5      u  n[        U R                  U R                  5      u  nX4$ rI   )r  r#  r7  r$  )rE   variable_true_outputvariable_false_outputs      r;   get_variable_outputs#OutputSelector.get_variable_outputs  sO    "3$$!!#
	 $5%%!!$
 	 $::r=   c                    [        U R                  U R                  5      u  n[        XR                  4X R                  45      nU$ rI   )r  r#  r:  r  r7  )rE   variable_resultsconstant_outputrestored_outputs       r;   #restore_outputs_by_variable_results2OutputSelector.restore_outputs_by_variable_results  sN    .$$!!

 @445334
 r=   c           
       ^
^ SSK Jn  SSKJm
  [        [
        [        4m[        U 6 u  p4S nS nS n[        S U 5       5      (       a  U$ [        S U 5       5      (       a  U$ [        U4S	 jU 5       5      (       as  U" U5      (       af  U" U5      (       a  U$ [        R                  " S
[        US   5       SUS    SUS    S35        U  VV	s/ s H  u  p[        X)5      " US S9PM     sn	n$ [        S U 5       5      (       a  [        U4S jU 5       5      (       af  [        R                  " SS[        US   5       S3-   S[        US   5       S3-   5        U  VV	s/ s H  u  p[        X)5      " X" U5      S9PM     sn	n$ [        U
4S jU 5       5      (       a9  [        R                  " SU SU S3S-   5        U  Vs/ s H  nT
" U5      PM     sn$ [        SU SUS    SUS    S35      es  sn	nf s  sn	nf s  snf )Nr   r  rQ  c                T   ^  [        T 5      S::  a  g[        U 4S jT SS   5       5      $ )Nr   Tc              3  2   >#    U  H  oTS    :H  v   M     g7fr   Nr]   r  outoutss     r;   r  \OutputSelector.constant_to_variable_promotion.<locals>.all_has_same_value.<locals>.<genexpr>  s     :#d1g~s   r   r  rN  s   `r;   all_has_same_valueIOutputSelector.constant_to_variable_promotion.<locals>.all_has_same_value  s(    4yA~:ab:::r=   c                T   ^  [        T 5      S::  a  g[        U 4S jT SS   5       5      $ )Nr   Tc              3  V   >#    U  H  n[        U5      [        TS    5      L v   M      g7frK  r   rL  s     r;   r  [OutputSelector.constant_to_variable_promotion.<locals>.all_has_same_type.<locals>.<genexpr>  s"     FXctCyDaM1Xs   &)rP  rQ  s   `r;   all_has_same_typeHOutputSelector.constant_to_variable_promotion.<locals>.all_has_same_type  (    4yA~FT!"XFFFr=   c                    U  H:  n[        U[        R                  R                  5      (       d  M.  UR                  s  $    g rI   )rB   r&  rH  rI  r1  )rN  rM  s     r;   get_first_value_dtypeLOutputSelector.constant_to_variable_promotion.<locals>.get_first_value_dtype  s2    c6::#3#34499$  r=   c              3  j   #    U  H)  n[        U[        R                  R                  5      v   M+     g 7frI   r1  r  rM  s     r;   r  @OutputSelector.constant_to_variable_promotion.<locals>.<genexpr>  $     ADSz#vzz//00D   13c              3  (   #    U  H  oS L v   M
     g 7frI   r]   r^  s     r;   r  r_    s     +dsd{ds   c              3  <   >#    U  H  n[        UT5      v   M     g 7frI   rB   r  rM  promotion_builtin_typess     r;   r  r_    s      
@DJs344   z>Return results from different branches in cond has same type: z*, but has different value: true value is 'z' and false value is 'r   z/', so we will promote the constant to variable.r1  c              3  j   #    U  H)  n[        U[        R                  R                  5      v   M+     g 7frI   r1  r^  s     r;   r  r_    r`  ra  c              3  t   >#    U  H-  n[        U[        R                  R                  /TQ75      v   M/     g 7frI   r1  re  s     r;   r  r_    s6      J
 sVZZ--H0GHIIs   58zBReturn results from different branches in cond are not same type: z#false_var returned by false_fn is 'z' and true_var of true_fn is 'c              3  <   >#    U  H  n[        UT5      v   M     g 7frI   rd  )r  rM  rQ  s     r;   r  r_  $  s     =z#|,,rg  z1Return results has maybe unbound local variable `z`, please ensure do not use ``zafter cond.zMUnsupported return type of true_fn and false_fn in cond: false_var returned `z` by false_fn is `z` and true_var of true_fn is `)r  r  r  rQ  r%   r2   r  r  r  r)  r*  r-   r  anyrC   )out_with_blocksr(   r  rN  r  rR  rW  r[  rM  rj   rQ  rf  s             @@r;   r!  -OutputSelector.constant_to_variable_promotion  sk   M;#'e"4'	;
	G
	 ADAAAK+d+++K 
@D
 
 
%%!$''TUYZ^_`ZaUbTc d??CAwiG]^bcd^e]f gCC '6	 '6
 ##5=cN&5	  ADAAAc J
J
 G
 G
 MMT7T!WFcded47m_A&' #2	 #2JC 194T: #2	  ====MMCD6Ifgkfllmn  1@@1L&@@0a	9WX\]^X_W``ac
 	
=  As   G7$!G=Hc                  ^ [        U 6 u  mn[        R                  " 5       nUR                  n[        R                  R
                  [        R                  R                  /nXE;  a  T$ S nU4S jn[        S T 5       5      (       aN  U" T5      (       dA  [        R                  " STS   R                   STS   R                   S35        U" U 5      mT$ T$ )	Nc                T   ^  [        T 5      S::  a  g[        U 4S jT SS   5       5      $ )Nr   Tc              3  Z   >#    U  H   oR                   TS    R                   :H  v   M"     g7frK  rh  rL  s     r;   r  QOutputSelector.precision_promotion.<locals>.all_has_same_dtype.<locals>.<genexpr>A  s      FXcyyDGMM1Xs   (+rP  rQ  s   `r;   all_has_same_dtype>OutputSelector.precision_promotion.<locals>.all_has_same_dtype>  rY  r=   c                   > U4S jn/ nU" U 5      nU  HM  u  pEX4R                   :w  a(  [        [        R                  U5      " U[        U   5      nUR                  U5        MO     U$ )Nc                   > [        T5      S::  a  TS   R                  $ [        S U  5       5      (       a'  [        S U  5       5      (       a  [        R                  $ U S   S   R                  $ )Nr   r   c              3  `   #    U  H$  u  pUR                   [        R                  :H  v   M&     g 7frI   )r1  r&  float16r  rM  r  s      r;   r  pOutputSelector.precision_promotion.<locals>.promote_precision.<locals>.get_expected_precision.<locals>.<genexpr>H  s"      >MFCCII/o   ,.c              3  `   #    U  H$  u  pUR                   [        R                  :H  v   M&     g 7frI   )r1  r&  float32r{  s      r;   r  r|  J  s"      >MFCCII/or}  )r   r1  rn  r&  r  )ro  rN  s    r;   get_expected_precision]OutputSelector.precision_promotion.<locals>.promote_precision.<locals>.get_expected_precisionD  sr    t9>7==( >M   >M   ">>)*1-a0666r=   )r1  r  r&  rz  r   r   )ro  r  new_outsexpected_dtyperM  rj   rN  s         r;   promote_precision=OutputSelector.precision_promotion.<locals>.promote_precisionC  sd    7 H3ODN-
!YY.(e<<^LC $ . Or=   c              3  j   #    U  H)  n[        U[        R                  R                  5      v   M+     g 7frI   r1  r^  s     r;   r  5OutputSelector.precision_promotion.<locals>.<genexpr>[  s'      
9=#JsFJJ,,--ra  zYReturn results from different branches in cond has different dtype: true value dtype is 'r   z' and false value dtype is 'r   z<', so we will promote the lower precision to the higher one.)r  r	   ru  rv  rw  rx  ry  r  r)  r*  r1  )	ro  r(   r  r{  r|  r}  ru  r  rN  s	           @r;   r"  "OutputSelector.precision_promotion0  s    'a'')	((	MMMM 
 0K	G
	0  
9=
 
 
$T**MMklpqrlslylykz  {W  X\  ]^  X_  Xe  Xe  Wf fL L %_5DKr=   )r  r   r  r  r  N)rW   rX   rY   rZ   rF   r   r'  ro  r#  r$  r7  r:  r?  rE  staticmethodr!  r"  r\   r]   r=   r;   r  r    s    	- 9 96 & & & & % % 
 
	;
 I
 I
V 4 4r=   r  c           
     j  ^ ^!^" [        5       (       a  [        U [        5      (       d   S5       eU R                  S:X  d   S5       eU R	                  5       n U (       a=  Ub8  [        U5      (       d!  [        S[        U5      R                   35      eU" 5       $  gUb8  [        U5      (       d!  [        S[        U5      R                   35      eU" 5       $ gSnSn[        U SS/S	5        [        US
[        [        S5      4S	5        [        5       (       a  [        U 5      nUbQ  [        U5      (       d!  [        S[        U5      R                   35      eUR                  5          U" 5       nSSS5        UbS  [        U5      (       d!  [        S[        U5      R                   35      eUR                  5          U" 5       nSSS5        GO	GO[!        S0 [#        5       D6m U 4S jnUbj  [        U5      (       d!  [        S[        U5      R                   35      e[%        U /SS9n	U	R'                  5          U" 5       n
U
b  [)        X5      nSSS5        Ub~  [        U5      (       d!  [        S[        U5      R                   35      e[%        [*        R,                  " U 5      /SS9nUR'                  5          U" 5       nUb  [)        X5      nSSS5        Uc  Uc  gUc  [/        S5      eUc  [/        S5      eUc  SnS/[1        [3        U5      5      -  nO Sn[5        XVU5      u  pV[1        [3        U5      5      [1        [3        U5      5      :w  a6  [/        S[1        [3        U5      5       S[1        [3        U5      5       S35      e[7        [3        U5      [3        U5      [3        U5      5       H  u  pn [9        XSS9  M     S nU" [3        U5      [3        U5      [3        U5      5        U(       a  [;        5       (       d  [=        XV5      u  pV[        5       (       Ga  [?        U5      [?        U5      nn[7        [3        U5      [3        U5      5       VVVs/ s H  u  nn[?        U5        H  nUPM     M     nnnn[A        WUUUS9nURC                  5       u  nnUR                  5          [E        U5        SSS5        UR                  5          [E        U5        SSS5        URG                  5         [?        URI                  5       5      nURK                  U5      n[M        UU5      $ [*        RN                  " U SS9m!U!4S jm"U"4S jn[Q        [S        U[3        U5      [3        U5      [3        U5      5      5      n[)        S U5      n[M        U[?        U5      5      nU$ ! , (       d  f       GN:= f! , (       d  f       GN= f! , (       d  f       GN= f! , (       d  f       GN= f! [.         a  n[/        SU SU 35      eSnAff = fs  snnnf ! , (       d  f       GNb= f! , (       d  f       GNP= f) ac  
This API returns ``true_fn()`` if the predicate ``pred`` is true else
``false_fn()`` . Users could also set ``true_fn`` or ``false_fn`` to
``None`` if do nothing and this API will treat the callable simply returns
``None`` in this case.

``true_fn`` and ``false_fn`` should return same nest structure of tensors
or both return ``None`` if user doesn't like to return anything. A nest
structure of tensors in PaddlePaddle is tensor(s), or tuple of tensors, or
list of tensors.

Note:
    1. The tuples or lists returned by ``true_fn`` and ``false_fn`` must have
    the same shape because of dataflow model of PaddlePaddle while the
    tensors in the tuples or the lists can have different shapes.

    2. This API could be used under both static graph mode or dygraph mode. If it
    is in dygraph mode, the API only runs one branch based on condition.

    3. If it is in static graph mode, any tensors or operations created outside
    or inside of ``true_fn`` and ``false_fn`` will be in net building
    regardless of which branch is selected at runtime. This has frequently
    surprised users who expected a lazy semantics.

    Examples:
        .. code-block:: python
            :name: code-example-1

            >>> import paddle

            >>> a = paddle.zeros((1, 1))
            >>> b = paddle.zeros((1, 1))
            >>> c = a * b
            >>> out = paddle.static.nn.cond(a < b, lambda: a + c, lambda: b * b)

    No matter whether ``a < b`` , ``c = a * b`` will be in net building and
    run. ``a + c`` and ``b * b`` will be in net building, but only one
    branch will be executed during runtime.

Args:
    pred(Tensor): A boolean tensor whose numel should be 1 (shape []
        or shape [1]). The boolean value determines whether to return the
        result of ``true_fn`` or ``false_fn`` .
    true_fn(callable, optional): A callable to be performed if ``pred`` is
        true. The default value is ``None`` .
    false_fn(callable, optional): A callable to be performed if ``pred`` is
        false. The default value is ``None`` .
    name(str, optional): The default value is ``None`` . Normally users
         don't have to set this parameter. For more information, please
         refer to :ref:`api_guide_Name` .
    return_names(sequence of string, optional): The default value is ``None`` .
         Normally users don't have to set this parameters.  A sequence of strings
         to represents the name of returned vars.  The structure of sequence must
         be same with return values of true_fn and false_fn.

Returns:
    Tensor|list(Tensor)|tuple(Tensor): returns ``true_fn()`` if the
    predicate ``pred`` is true else ``false_fn()`` .

Examples:
    .. code-block:: python
        :name: code-example-2

        >>> import paddle

        >>> # pseudocode:
        >>> # if 0.1 < 0.23:
        >>> #     return 1, True
        >>> # else:
        >>> #     return 3, 2

        >>> def true_func():
        ...     return paddle.full(shape=[1, 2],
        ...                        dtype='int32',
        ...                        fill_value=1
        ...         ), paddle.full(shape=[2, 3],
        ...                        dtype='bool',
        ...                        fill_value=True
        ...         )


        >>> def false_func():
        ...     return paddle.full(shape=[3, 4],
        ...                        dtype='float32',
        ...                        fill_value=3
        ...         ), paddle.full(shape=[4, 5],
        ...                        dtype='int64',
        ...                        fill_value=2
        ...         )


        >>> x = paddle.full(shape=[1], dtype='float32', fill_value=0.1)
        >>> y = paddle.full(shape=[1], dtype='float32', fill_value=0.23)
        >>> pred = paddle.less_than(x=x, y=y, name=None)
        >>> a, b = paddle.static.nn.cond(pred, true_func, false_func)

        >>> print(a)
        Tensor(shape=[1, 2], dtype=int32, place=Place(cpu), stop_gradient=True,
               [[1, 1]])
        >>> print(b)
        Tensor(shape=[2, 3], dtype=bool, place=Place(cpu), stop_gradient=True,
               [[True, True, True],
                [True, True, True]])
z!The pred in cond must be Variabler   z#condition input's numel should be 1Nz3The true_fn in cond must be callable, but received z4The false_fn in cond must be callable, but received r  r%   zpaddle.static.nn.condr(   c                   > [        U T5      $ rI   )copy_var_to_parent_block)r   r9   s    r;   r   cond.<locals>.<lambda>  s    *B3*Or=   Tr   zpIncompatible return values of true_fn and false_fn in cond: true_fn returns None while false_fn returns non-NonezpIncompatible return values of true_fn and false_fn in cond: true_fn returns non-None while false_fn returns NoneFzno nameztrue fn returns z vars, but false fn returns z vars, which is not equalsr  zIncompatible return values of `z#` in true_fn and false_fn in cond: c                B   [        XU5       H  u  p4n[        U5      n[        U5      n[        [        U5      5       H[  nX6   c  XF   c  XF   b  M  X6   c  M  [        R
                  " SU S[        X6   5       SX6    S[        XF   5       SXF    S35        M]     M     g )NIn cond : Var '8' or part of it is set differently in ifelse branches, <, > in true branch and <I> in false branch. Set var to 'None' in ifelse block might lead to error.)r  r   r  r   r)  r*  r-   )seq_true	seq_false	seq_namesf_truef_falsef_namer   s          r;   check_ret_nonecond.<locals>.check_ret_noneI  s    '*8	'J#FVV_Fg&GS[)K'0|+/MM)& 2 -.b=STXY`YeTfSggijqjviw xFF * (Kr=   )r  r  rh  c                    > [        X/TU 5      $ rI   )select_input_with_buildin_type)r(   	false_vartrue_varmasks      r;   r   r    s    *H!4+
r=   c                0   > [        [        TU5      X5      $ rI   )r    r   )
false_vars	true_varsr(   
merge_funcs      r;   merge_every_var_list"cond.<locals>.merge_every_var_list  s    WZ6
NNr=   c                    U " 5       $ rI   r]   )r  s    r;   r   r    s    RTr=   )r$   )*r   rB   r   sizer  r  rC   r-   rW   r   r   r3   r   r   r   r   r   r4   r   rj   r    r&  logical_notr  r   _to_sequence_except_dictexpand_undefined_varr  r   r   change_none_to_undefinedvarr   r  r?  r   update_outputr  rE  r!   rz  r0   map)#r  r  r  r(   return_namesr  r  r   copy_to_parent_functrue_cond_blockorigin_true_outputfalse_cond_blockorigin_false_outputis_dy2staticr%  r&  return_namer  r  r  r  seq_outr  flattened_return_namesoutput_selectorr=  r>  rB  rD  r  merged_output_fnsmerged_outputr9   r  r  s#                                   @@@r;   r$   r$   h  sK   R $))N+NN)yyA~DDD~yy{"((#MdSZmNdNdMef  y  #  #))#NtT\~OfOfNgh   z!KLT6F85LMtVc4:.0GH}}D!G$$I$w-J`J`Iab  !!#%i $H%%J4PX>KbKbJcd  ""$'z %$   0vx0OG$$I$w-J`J`Iab  /v4PO &&(%,Y"%1"/+#K ) H%%J4PX>KbKbJcd   0##D)*  "'')&.j#&2#0+$L * |3C
 	
 C
 	
 !{S)A+)N%OO	  %9|%
! #K01S .6  s#;K#HIJJfgj  lD  EQ  lR  hS  gT  Tn  o
 	
 -0 - . .-([
	!(5I-"  - . . KMM$?%
! }}K L!  6 "%(5(6""
" W% 
 & " 	 "
 )!"(	
 002	
 ! )*   *+ ! 	"5==?3)MM
  _==;;t7+D	
 O  $\2$[1$\2		
 "/3DEM$\7=3IJM_ $# %$ )( *)j  	1+>abcade 	L"
&    sf   $V8V14W5W4
W'"X
*XX#
V.1
W 
W
W$'
X1XX
X #
X2c                   [        U [        5      (       d  U $ UR                  nUR                  5       R                  nUS:  d   S5       eUR                  U5      nU R                  [        R                  R                  R                  :X  a$  UR                  U R                  5      (       a  U nU$ UR                  U R                  U R                  U R                  S9n[         R"                  " X5        U$ )Nr   zOGot wrong parent block index when assigning var to parent scope in control_flowr1  r   r-   )rB   r   rD   r   r   rj   r-   r	   r   r   r   r   r(   r   r1  r   r&  r'  )r   layer_helperprogr   r   r  s         r;   r  r    s    c8$$
$$D##%00J? Y? ::j)L 	DLL((;;;,,SXX66 	 (22))399388 3 
 	c,r=   c                    [        S	0 [        5       D6n[        U S[        S5        [	        USS/S5        [        US[
        [        4S5        UR                  SXS.SU0S9  U$ )
a  
**select_output**
This API takes in one input and multiple outputs and an integer mask. It
selects the output specified by the mask and copy the input to selected
output. It is useful in control flow.

Args:
    input(Variable): The input variable
    outputs(tuple|list): The output variables
    mask(Variable): A tensor containing 1 integer number selecting which
        output to be copied with input

Returns:
    Variable: The outputs variables
select_outputr   r  r  r   r  Maskr   r-   r.   r   )r  )r   r4   r   r   r   r0   r1   r5   )r   r   r  r9   s       r;   r  r    sn      5FH5Fug?;T6G9oFw	D%=/B
)   
 Nr=   c                    [        U 5      [        U5      :w  a  [        R                  " SU  SU 35        U$ [        X5       VVs/ s H  u  p#X#:X  a  UOSPM     nnnU$ s  snnf )a  
This function infer the output shape by following algorithm:
1. if the dims is different, raise a error.
2. compare axis one by one:
    if a == b: we set axis to a
    if a != b: we set axis to -1
for compatibility, non declarative mode, we just return second_shape.
zDthe input shapes of select_input should have the same rank, but get r  r   )r   r)  r*  r  )first_shapesecond_shaper}   r~   	out_shapes        r;   _select_input_infer_shaper    sq     ;3|,,RS^R__abnaop	
 14[1OP1Oaf"$1OIP Qs   Ac                L   [        S0 [        5       D6n[        U S[        [        4S5        [        USS/S5        [        U S   R                  U S   R                  5      nU S   R                  nU S   R                  nUR                  XCUS9nUR                  SXS.S	U0S
9  U$ )aQ  
**select_input**

This API takes in multiple inputs and uses an integer mask to select one
input to output. It is useful in control flow.

Args:
    inputs(tuple|list): The input variables
    mask(Tensor): A tensor containing 1 integer number selecting which
        input to output

Returns:
    Variable: The selected input variable
select_inputr.   r  r  r   r   r  r  r   r  )r  )r   r4   r   r0   r1   r   r  r   r1  r-   create_variabler5   )r.   r  r9   output_shapeoutput_dtypeoutput_typerM  s          r;   r  r    s     4684Fvx$?T6G9nE
 -VAY__fQiooNL!9??L)..K

 
 [ ! C *  
 Jr=   c                  ^ ^^^ SSK Jn  SSKJn  T u  mnU UU4S jn[	        TU5      (       a  [	        XT5      (       a   S $ [	        T[
        5      (       a  [	        U[
        5      (       a  U$ [	        T[        5      (       a9  [	        T[        U5      5      (       a  TU:X  a  U4S j$ U" T5      U" U5      /m  U$ [	        T[        5      (       a  [	        U[
        5      (       d*  [	        U[        5      (       aV  [	        T[
        5      (       aA  U" T5      U" U5      /m [        R                  " S[        T5       S[        U5       S	35        U$ [	        TU5      (       a  [	        U[
        /[        Q75      (       d-  [	        XT5      (       a4  [	        T[
        /[        Q75      (       a  U" U5      U" T5      snmTU/m U$ [        S
[        T5       S[        U5       S	35      e)Nr   r  rH  c                 d   >  [        TT5      $ ! [         a  n [        ST SU  35      eS n A ff = f)Nz.Exceptions thrown while doing select_input on z:
)r  	ExceptionRuntimeError)r  r.   r  r(   s    r;   start_select_input:select_input_with_buildin_type.<locals>.start_select_input  sB    	-- 	@c!M 	s    
/*/c                     g rI   r]   r]   r=   r;   r   0select_input_with_buildin_type.<locals>.<lambda>  s    tr=   c                    > T $ rI   r]   )r  s   r;   r   r  '  s    9r=   zeReturn results from different branches in cond are not same type: false_var returned by false_fn is 'z' and true_var of true_fn is 'rk  z\Unsupported return type of true_fn and false_fn in cond: false_var returned by false_fn is ')r  r  r  rQ  rB   r   r%  r-   r)  r*  rC   )r.   r  r(   r  rQ  r  r  r  s   ```    @r;   r  r    s   I7 Ix )\**z0 0 	v)X&&:h+I+I!!	I7	8	8Z4>> >  $$ #9-"8,FF ; 	9677x**8566y(++$Y/1CH1MN226y/1B CXq"	
, ! 	9l++x(!F-E!FGG8**y8"G.F"GHH x(y) 	) X& 	 ((,Y'88VW[\dWeVffgi
 	
r=   c                D    [        U [        5      (       a  g[        U 5      $ )3
In this function, dict is not viewed as sequence.
F)rB   r  r   r  s    r;   _is_sequence_except_dictr  O  s     !Tq>r=   c                H    [        U [        5      (       a  U /$ [        U 5      $ )r  )rB   r  r"   r  s    r;   r  r  X  s"     !Ts
q>r=   c                  ^^^	 SSK Jm  SSKJm  U4S jm	UUU	4S jn[	        [        U[        U 5      [        U5      [        U5      [        U5       Vs/ s H  nSPM     sn5      5      n[	        [        U[        U5      [        U 5      [        U5      [        U5       Vs/ s H  nSPM     sn5      5      n[        U 5      (       d  US   n[        U5      (       d  US   nXV4$ s  snf s  snf )zTODO: make this function recursively.
nest1: Var1, (UndefinedVar, [1,2,3])
nest2: Var2, ([1,2,3,4], UndefinedVar)
In this case, we should not expand recursively.
r   )RETURN_VALUE_PREFIXrH  c           	     f   > [        U [        U 5       Vs/ s H  nT" S5      PM     sn5      $ s  snf Npadding)r!   r   )seqr   rQ  s     r;   pack_undefined_var_as3expand_undefined_var.<locals>.pack_undefined_var_asl  s0    73<@<a,y)<@
 	
@s   .
c                f  > UR                  T5      (       d  [        U T5      (       d  U c  U cz  Ubw  US:X  a9  [        R                  " SU S[	        U 5       SU  S[	        U5       SU S35        O8[        R                  " SU S[	        U5       SU S[	        U 5       SU  S35        T" U5      $ U $ )Nr   r  r  r  r  r  )
startswithrB   r)  r*  r-   )n1n2r(   orderr  rQ  r  s       r;   map_fn$expand_undefined_var.<locals>.map_fnq  s    233r<((BJzbnA:MM)$ 0 H:Rt+A$r(2bT RFF MM)$ 0 H:Rt+A$r(2bT RFF
 ),,	r=   r   )4paddle.jit.dy2static.transformers.return_transformerr  r  rQ  r0   r  r  r  )
nest1nest2r  r  r   	nest1_out	nest2_outr  rQ  r  s
          @@@r;   r  r  a  s     8

( $U+$U+$U+07871Q78	
I $U+$U+$U+07871Q78	
I $E**aL	#E**aL	! 9 9s   C%!C*c                   ^ SSK Jm  U4S jn[        U [        [	        U[        U 5      5      5      5      n[        U[        [	        U[        U5      5      5      5      nX44$ )Nr   rH  c                   > U c  T" S5      $ U $ r  r]   )r  rQ  s    r;   r  +change_none_to_undefinedvar.<locals>.map_fn  s    9	**r=   )r  rQ  r!   r0   r  r   )r  r  r  r  r  rQ  s        @r;   r  r    sN    7
 !S-H(IJI S-H(IJIr=   c
                   [        U S/ SQS5        U=(       d    Sn[        S0 [        5       D6n
[        5       (       a.  [        R
                  " U UUUUUUUUU	R                  5       S5      $ U
R                  U R                  5      nU
R                  SSU 0SU0UUU=(       d    SUUUUUU	R                  5       S	.	S
9  U$ )a	  
:api_attr: Static Graph

**Print operator**

This creates a print op that will print when a tensor is accessed.

Wraps the tensor passed in so that whenever that a tensor is accessed,
the message `message` is printed, along with the current value of the
tensor `t`.

Args:
    input (Tensor): A Tensor to print.
    first_n (int, optional): Only log `first_n` number of times. Default: -1.
    message (str, optional): A string message to print as a prefix. Default: None.
    summarize (int, optional): Number of elements in the tensor to be print. If
            it's value is -1, then all elements in the tensor will be print.
    print_tensor_name (bool, optional): Print the tensor name. Default: True.
    print_tensor_type (bool, optional): Print the tensor type. Default: True.
    print_tensor_shape (bool, optional): Print the tensor shape. Default: True.
    print_tensor_layout (bool, optional): Print the tensor layout. Default: True.
    print_tensor_lod (bool, optional): Print the tensor lod. Default: True.
    print_phase (str, optional): Which phase to displace, including 'forward',
            'backward' and 'both'. Default: 'both'. If set to 'backward', will
            only print the gradients of input tensor; If set to 'both', will
            both print the input tensor itself and the gradients of input tensor.

Returns:
    Tensor: Output tensor.

NOTES:
    The input and output are two different Tensor, and in the
    following process, you should use the output Tensor but not the input,
    otherwise, the print layer doesn't have backward.

Examples:
    .. code-block:: python

        >>> import paddle

        >>> paddle.enable_static()

        >>> x = paddle.full(shape=[2, 3], fill_value=3, dtype='int64')
        >>> out = paddle.static.Print(x, message="The content of input layer:")

        >>> main_program = paddle.static.default_main_program()
        >>> exe = paddle.static.Executor(place=paddle.CPUPlace())
        >>> res = exe.run(main_program, fetch_list=[out])
        >>> # doctest: +SKIP('Unable to get output')
        Variable: fill_constant_1.tmp_0
          - message: The content of input layer:
          - lod: {}
          - place: Place(cpu)
          - shape: [2, 3]
          - layout: NCHW
          - dtype: int64
          - data: [3 3 3 3 3 3]
        >>> # doctest: -SKIP
        >>> res
        [array([[3, 3, 3],
                [3, 3, 3]], dtype=int64)]
r   )	uint16rz  r  float64r  r  r%   float8_e4m3fnfloat8_e5m2zpaddle.static.Print printTInr   )	first_nr'   messageprint_tensor_nameprint_tensor_typeprint_tensor_shapeprint_tensor_layoutprint_tensor_lodprint_phaser   )r  )
r   r   r4   r   r   r  upper"create_variable_for_type_inferencer1  r5   )r   r  r  r'   r  r   r  r  r  r  r9   r   s               r;   Printr    s    V 
	
 	  mG-FH-F}}||
 	
 66u{{CF
e}"}"!2!2"4#6 0&,,.

	    Mr=   c                  6    \ rS rSrS	S jrS rS rS rS rSr	g)
Switchi,	  Nc                >    [        SUS9U l        SU l        / U l        g )Nswitchr   F)r   r9   inside_scopepre_not_conditions)rE   r(   s     r;   rF   Switch.__init__-	  s     !(6!"$r=   c                "   U R                   (       d  [        S5      e[        USS/S5        [        U R                  5      S:X  a;  [        U/SS9n[        R                  " US9nU R                  R                  U5        O[        U R                  5      nU R                  US	-
     n[        R                  " U[        R                  " US9S
9nU R                  R                  U5        [        [        R                  " XQS
9/SS9n[        U5      $ )Nz!case should be called inside with	conditionr%   z.the member function case of base.layers.Switchr   Tr  r  r   )r  y)r  r  r   r   r  r   r&  r  r   logical_andr   )rE   r  
cond_blocknot_condpre_cond_numpre_not_condnew_not_conds          r;   r  Switch.case2	  s      @AA H<		
 t&&'1,)9+4PJ))I6H##**84t667L22<!3CDL!--&"4"4y"AL ##**<8)##l@A$(J
 %Z00r=   c                    [        U R                  5      nUS:X  a  [        S5      e[        U R                  US-
     /SS9n[	        U5      $ )Nr   z&there should be at least one conditionr   Tr  )r   r  r  r   r   )rE   r  r  s      r;   r  Switch.defaultO	  sV    42231EFF%$$\A%567 $

 %Z00r=   c                    SU l         U $ )z6
set flag that now is inside switch.block {}
:return:
Tr  rK   s    r;   rL   Switch.__enter__Y	  s    
 !r=   c                    SU l         Ub  ggrO   r  rQ   s       r;   rU   Switch.__exit__a	  s    !r=   )r9   r  r  rI   )
rW   rX   rY   rZ   rF   r  r  rL   rU   r\   r]   r=   r;   r	  r	  ,	  s    %
1:1r=   r	  )N   Nr   rn  )NNNN)	r   Nr   TTTTTboth)R
__future__r   r)  	functoolsr   r   r   typingr   r&  r   paddle.baser	   paddle.base.backwardr
   paddle.base.frameworkr   r   r   r   r   paddle.base.libpaddle.pirr   r   r   r   paddle.common_ops_importr   r   r   r   r   paddle.frameworkr   paddle.pir.corer   paddle.utilsr   r   r   r   r   r    r!   r"   r<   r?   r_   rx   r   r   r   rb   r%   r  r2   r%  r.  r?  rA  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;   <module>r-     s   #  6 6     <    ) ;	 	 	HV .; ;4(( ((Vv2 v2r;J ;*<'~I
 I
X !%- +)\! 4j 4jnAH#Lxvxv		_ _Dvr	.:$"J@F: z
   } }@9 9r=   