o
    * i[                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ d d
lmZ g ZdZdZdZdZdZdZ dZ!dd Z"dd Z#dd Z$dd Z%dd Z&dd Z'edd Z(ed d! Z)d"d# Z*ed$d% Z+d&d' Z,dOd(d)Z-ed*d+ Z.d,d- Z/G d.d/ d/Z0	dPd0d1Z1d2d3 Z2d4d5 Z3dPd6d7Z4	8dQd9d:Z5d;d< Z6d=d> Z7d?d@ Z8dAdB Z9	dPdCdDZ:	dPdEdFZ;dGdH Z<dIdJ Z=	dOdKdLZ>G dMdN dNej?Z@dS )R    N)_legacy_C_ops)backwardcore	frameworkunique_name)
check_type)switch_to_static_graph)OpProtoHolder)in_dynamic_mode)LazyInitializedadd_build_strategy_for)construct_grad_names)layersz.pdmodelz
.pdiparamsz.pdiparams.infoz.metaloadparambufferc                 C   sb   t | d}| }W d    n1 sw   Y  t|}t| s/td|  d|S )NrbzUnsupported program version: 
)openreadr   ProgramDescZ_is_program_version_supported_version
ValueError)model_file_pathfZprogram_desc_strprogram_desc r   g/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/paddle/jit/translated_layer.py_load_program_desc.   s   

r   c                 C   sT   |   tjjjks$|   tjjjks$|   tjjjks$|   tjjjkr&dS |  S )NF)	typer   VarDescVarTypeZFEED_MINIBATCHZ
FETCH_LISTZREADERZRAWpersistable)var_descr   r   r   _is_persistable;   s   r$   c                 C   s   g }t | D ]"}||}t | D ]}||}|  | v r)|| qqt | D ]&}||}t | D ]}||}|  | v rV||v rRq>  dS q>q1dS NFT)	range
num_blocksblockop_sizeopnameinput_arg_namesappendoutput_arg_names)Zpersistable_var_descr   Z	input_ops	block_idxr(   op_idxr*   r   r   r   _is_parameterF   s(   




r1   c                 C   s<   g }t |  D ]}| |}|ttt|  q|S N)r&   r'   r(   extendlistfilterr$   all_vars)r   persistable_varsir(   r   r   r   _get_persistable_vars^   s
   
r9   c                 C   s(   g }t | }|D ]	}||  q|S )z<
    Get all persistable variable names in ProgramDesc.
    )r9   r-   r+   )r   Z	var_namesr7   varr   r   r   _get_persistable_var_namesf   s
   r;   c                 C   sB   t  }t|  D ]}| |}| D ]	}||  qq	|S r2   )setr&   r'   r(   r6   addr+   )r   all_var_namesr8   r(   r:   r   r   r   _get_all_var_namesq   s   
r?   c                 C   s   t }td| |f}|S )zo
    Append loaded suffix to the given variable name
    e.g. x ==> x.load_0, x.load_0 ==> x.load_0.load_0
    .)LOADED_VAR_SUFFIXr   generate_with_ignorable_keyjoin)r+   suffixnew_namer   r   r   _append_loaded_suffixz   s   rF   c                 C   
   t | S r2   )r   rB   prefixr   r   r   _generate_unique_var_name      
rJ   c           
      C   s   i }t | }|D ]G}| }t| }|||< || t|  D ]+}| |}|| |  t|	 D ]}|
|}	|	|| |	|| q:q#q|S r2   )r9   r+   rF   set_namer&   r'   r(   _rename_varencoder)   r*   _rename_input_rename_output)
r   Zsuffix_varname_dictr7   r#   Zold_namerE   r/   r(   r0   r*   r   r   r   _append_loaded_suffix_to_var   s"   


rQ   c                 C   rG   r2   )r   generaterH   r   r   r   0_generate_unique_var_name_sync_with_main_program   rK   rS   c                 C   s.   i }t | }|D ]}| }|| ||< q|S r2   )r9   r+   )r   Zall_new_old_dict_allZnew_old_dictr7   r#   name_newr   r   r   _get_loaded_var_new_old   s   rU   c                 C   s  i }i }g }t |  D ]}| |}| D ]	}||  qqd}	t |  D ]}| |}t| D ]t\}
}| }d|v }|	pF|}	|du sO||v oY|du pV||voY| }|r|d}t|dkrw|d 	 rwd
|dd }n|}	 t|}||d|
 ||
d d  vrnqzn|}||kr|| |  |s|||< |||< q7q*|	ri }|D ]3}t |  D ]*}| |}t| D ]\}
}| }d|v r||v r|||| }|||< qqq|D ]}|| ||< |||| < qt |  D ]v}| |}t | D ]h}||}| D ]+}||v r@||| kr@||||  || r@|| ||   q| D ]+}||v rp||| krp||||  || rp|| ||   qFqq|   ||fS )a  
    Change the name of the loaded variables.Use 'unique_name.generate' to avoid duplication.
    It is used when loading multiple program during inference.

    e.g. linear_0.tmp_3 ==> linear_0.tmp_1, x ==> x_0. For double grad, x@GRAD ==> x_0@GRAD
    If 'include' is not `None`,variables in include and the corresponding
      double grad variables (if exist) are renamed.
    If 'exclude' is not `None`,variables that are in exclude and the
      corresponding double grad variables (if exist) are not renamed.

    Args:
        program_desc(ProgramDesc):the variables in it will be modified.
        include(List):list of names of variables.
        exclude(List):list of names of variables.

    Returns:
        tuple of (dict_rename_var_new_old, dict_rename_var_old_new)
        dict_rename_var_new_old is a dict mapping from new name to old name
        dict_rename_var_old_new is a dict mapping from old name to new name
    Fz@GRADN_   )r&   r'   r(   r6   r-   r+   	enumeratesplitlen	isnumericrC   rS   rM   rN   replacer)   r*   r,   rO   has_varr.   rP   flush)r   includeexcludedict_rename_var_old_newZdict_rename_var_new_oldZ	old_namesZb_idxZ	cur_blockr:   Zhas_double_gradZvar_idxZname_oldZis_double_grad_varZshould_renameZ	temp_namerT   Zdouble_grad_rename_dictvar_nameZnew_var_namer0   r*   Zinput_arg_nameZoutput_arg_namer   r   r   _rename_var_program_desc   s   


!
	



$rd   c                    s8   t   |  _ fddt j D  _    S )Nc                    s   g | ]}t  |qS r   )r   Block).0r8   progr   r   
<listcomp>1  s    z*_build_program_by_desc.<locals>.<listcomp>)r   Programdescr&   r'   blocks_sync_with_cpp)r   r   rg   r   _build_program_by_desc-  s   
rn   c                 C   sR   t |  D ] }| |}t | D ]}||}|dr%|d| qqd S )Nis_test)r&   r'   r(   r)   r*   has_attr	_set_attr)r   ro   r8   r(   jr*   r   r   r   _change_is_test_status8  s   


rs   c                       s   e Zd ZdZ fddZedd Zedd Zedd	 Z	ed
d Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zdd Zed d! Zed"d# Zed$d% Z  ZS )&_ProgramHolderz
    Holds the execution information of a Program.

    _ProgramHolder is the execution unit of TranslatedLayer,
    if TranslatedLayer contains multiple _ProgramHolder,
    it can execute multiple methods

    _ProgramHolder is an internal concept.
    c                    sB   t    g | _g | _g | _i | _t | _d | _	| 
|| _d S r2   )super__init___input_descs_output_descs_persistable_names_grad_var_namesr   ZScope_inner_scope_suffix_varname_dict_preprocess_infer_program_desc)selfr   	__class__r   r   rv   M  s   

z_ProgramHolder.__init__c                 C   s2   t | j}| jd }|dkrt|d|S |S Nr   )rn   train_programr~   r(   r)   r   )r   whole_programend_op_indexr   r   r   _create_forward_train_program_  s
   
z,_ProgramHolder._create_forward_train_programc                 C   
   |   jS r2   )r   rk   r   r   r   r   _forward_program_desch  rK   z$_ProgramHolder._forward_program_descc                 C   sR   t | j}| jd t| j }|jd }||k r$t|||S t	j
 S r   )rn   r   r~   r(   r)   r[   rx   rk   r   paddlestaticrj   )r   r   start_op_indexr   r   r   r   _create_backward_train_programm  s   

z-_ProgramHolder._create_backward_train_programc                 C   r   r2   )r   rk   r   r   r   r   _backward_program_desc{  rK   z%_ProgramHolder._backward_program_descc                 C      | j S r2   )r~   r   r   r   r   infer_program     z_ProgramHolder.infer_programc                 C   s   |  | jS r2   )_append_backward_descr~   r   r   r   r   r     s   z_ProgramHolder.train_programc                 C   r   r2   )r   r   r   r   r   forward_program  r   z_ProgramHolder.forward_programc                 C   r   r2   )r   r   r   r   r   backward_program  r   z_ProgramHolder.backward_programc                 C   r   r2   )rw   r   r   r   r   input_descs  r   z_ProgramHolder.input_descsc                 C   r   r2   )rx   r   r   r   r   output_descs  r   z_ProgramHolder.output_descsc                 C   r   r2   )ry   r   r   r   r   persistable_names  r   z _ProgramHolder.persistable_namesc                 C   r   r2   )r{   r   r   r   r   scope  r   z_ProgramHolder.scopec                 C   r   r2   )rz   r   r   r   r   grad_var_names  r   z_ProgramHolder.grad_var_namesc                 C   s  t |}t||\}}g }|d}t| D ]}||}| dkrI|| |dd 	 }	|
|	 | j||dd 	  q| dkr}|dd dr}|| |dd 	 }
|
|
 | j||dd 	  q| dkr|| |dd 	 }|
| |dd ds| j||dd 	  q|dr|d qt|D ]
}|||d	  q| j  t|}| | t||| _t || _|S )
Nr   feedXOutscalezsave_infer_model/scale_fetchZop_callstackrW   )r;   rd   r(   r&   r)   r*   r   r-   inputrN   Z_remove_varrw   find_varoutput
startswithrx   rp   Zremove_attrreversedZ
_remove_opreversern   _append_scale_to_outputrU   r|   ry   )r   r   Zlist_persistable_varZrename_new_old_dictrV   Zops_to_removeZ
root_blockr8   r*   Zfeed_var_nameZout_var_nameZfetch_var_namer0   Ztmp_programr   r   r   r}     s\   












z_ProgramHolder._preprocessc                 C   s   | j D ]}| tjkr d S qg }t|+ t| j D ]\}}| |	 }tj
|dd| d}|| qW d    n1 sEw   Y  t|D ]
\}}|j| j |< qNd S )Ng      ?ztranslated_layer/scale_r+   )rx   dtyper   boolr   Zprogram_guardrY   global_blockr:   r+   r   r-   rk   )r   programZout_descZscale_output_varsr8   outr:   r   r   r   r     s   
z&_ProgramHolder._append_scale_to_outputc              
   C   sl  t |}t|d t|}t|jD ]}||}|jD ]}|jdkrZd|j	vs2t
|ddkrY|jtdddg||dd jt jjjdd	d
}|jd|jg qt |jscqt |j}d}	|jD ]1}
|
jr|
j}||j	vrd	}	|jtd|jd | dgt jjjdd	d}|j||jg qp|	r|j|j |j |j qq|S )NFZ
batch_normZReserveSpacer   r@   reserve_spacetmpr   T)r+   r   r   r"   stop_gradientrV   )r+   r   r"   r   )!r   r   rs   rn   r&   r'   r(   opsr   Zoutput_namesr[   r   
create_varr   rB   rC   r:   r   r   r    r!   DENSE_TENSORrk   Z
set_outputr+   r	   instanceZhas_op_protoZget_op_protooutputsZintermediateZinfer_var_typeZinfer_shape)r   infer_program_descZprogram_desc_copyr   r/   r(   r*   r   protoZhas_create_intermediate_outZoutput_protoZintermediate_nameZintermediate_varr   r   r   _get_train_forward_program  sf   





	

2z)_ProgramHolder._get_train_forward_programc                    s   |  | g }| jD ]}|  |  q
t|dtjt	t
fd tj|g d} fdd| jD } fdd| jD } fdd| jD }t||||| _ jS )Ntargetszpaddle.static.gradients)r   inputsc                        g | ]}  d | qS r   r(   r:   r+   rf   rk   r   r   r   ri   _      z8_ProgramHolder._append_backward_desc.<locals>.<listcomp>c                    s   g | ]
}  d |qS r   )r(   r:   )rf   r+   r   r   r   ri   b  s    c                    r   r   r   r   r   r   r   ri   e  r   )r   rx   r-   r   r:   r+   r   r   Variabler4   tupler   Zcalc_gradient_helperrw   ry   r   rz   rk   )r   r   r   r   Zgrad_info_mapZx_varsZ
param_varsZout_varsr   r   r   r   M  s4   





z$_ProgramHolder._append_backward_desc)__name__
__module____qualname____doc__rv   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r}   r   r   r   __classcell__r   r   r   r   rt   B  sH    













S

Drt   c              
   C   s  t |j}i }|D ]U}|j|  }t||jr+tj| | | |	 dd}ntj
|	 | | | dd}|d u rUt jdi d|idtj| |id d|_||| < q	|d urg }d	d
 |j D }	t|	 D ]}
|||	|
   qut jdi d|idtj| |id |D ]}t||jsq||  }d|_qt|j}|D ]}|t  }||vrd|| _q|S )NT)shaper   r+   r   r"   )r   r+   r   r   r"   r   r   	file_pathr   r   r   attrsFc                 S      i | ]\}}||qS r   r   )rf   kvr   r   r   
<dictcomp>      
z5_load_persistable_vars_by_program.<locals>.<dictcomp>load_combine)r9   r   r|   r+   r1   r   EagerParamBaser   r   r   _create_tensor_dygraph_tracertrace_opospathrC   r   itemssortedkeysr-   r?   r   r   grad_var_suffix)
model_pathprogram_holderparams_filenamer7   load_var_dictZeach_varZorig_each_namenew_varload_var_listZdict_name_old_newr+   r   r>   rc   grad_var_namer   r   r   !_load_persistable_vars_by_program  sj   


r   c                 C   s:  t |d}t|}W d    n1 sw   Y  i }g }dd |j D }t|D ]>}	|	|vr7td|	||	 }
||	 dd d urStj	dgt
jjj|
dd}ntj|
dd	}||	 d
 |_|||
< || q,|d ussJ dtj| |}tj|st|dkrtd|S t jdi d|id|id |S )Nr   c                 S   r   r   r   )rf   keyvaluer   r   r   r     r   z*_load_persistable_vars.<locals>.<dictcomp>zdThe model to be loaded is not complete.The variable `%s` of program cannot be found in loaded model.Z	trainablerW   T)r   r   r+   r"   )r+   r"   r   z#params_filename should not be None.r   z%The model to be loaded is incomplete.r   r   r   r   )r   pickler   r|   r   r   RuntimeErrorgetr   r   r   r    r!   ZFP32r   r   r-   r   r   rC   existsr[   r   r   r   )r   var_info_pathr   r   r   Zextra_var_infor   r   Zinv_suffix_varname_dictr+   rE   r   Zvar_file_pathr   r   r   _load_persistable_vars  sN   	r   c                 C   s(   i }| D ]}|j | }| | ||< q|S r2   )r|   )var_dictr   Zno_suffix_var_dictrc   Zno_suffix_namer   r   r   _remove_varname_suffix  s
   
r   c                 C   sR  i }|d urrt j|}t j| |}|d tt  }t | D ]N}||kr1d}t j| |}n6|trf||rf|t|tt d  	d}t|dkret|d dkre|d }t j| |}nq!q!t
t|||< q!|S t | D ]/\}}}	|	D ]'}
d|
v rt j| |
}|
d}|dkrd}n|dd t
t|||< q~qw|S )	NforwardrW   r@      r   modelrV    )r   r   basenamerC   r[   INFER_MODEL_SUFFIXlistdirendswithr   rZ   rt   r   walkstripr]   )r   model_filenameZprogram_holder_dictr   
model_namefilename	func_nameparsing_namesrV   Z
file_namesr+   method_namer   r   r   _construct_program_holders  sP   

r   Tc                 C   s0  t |d }tj| |}tj| t |}tj|ryt| ||d |}|d tt  }t| D ]D}	|		|rc|	
trc|	t|tt d  d}
t|
dkrbt|
d dkrb|
d }nq3q3tj| |}|t| ||| |	 q3n|d urtj|si S t| |d |}|st||d }|S )Nz.infor   rW   r@   r   r   )strr   r   rC   r   r   r[   INFER_PARAMS_SUFFIXr   r   r   rZ   updater   r   )r   programsr   Zappend_suffixZvar_info_filenamer   Zparams_pathr   r   	file_namer   r   r   r   r   _construct_params_and_buffersF  sH   

r  c                 C   s   | r| S d S r2   r   )varsr   r   r   _valid_varst  s   r  c                 C   s  g }g }t |D ]F\}}t|tjtjjfs tdt| dt|tjr9tjj||j	| 
 dt dd}n
|}|j	| 
 |_
||j
 || q| jd u r]dd |j	D | _g }|jD ]*}	| j|	 }
|
| jv rw|| j|
  qb|
| jv r|| j|
  qbtd|	 d	g }|jD ]}tjj| | |
 | dd
}|| q|jg}| jr|jn|j}| jr|jn|j}|jd }d|dddd|d| jdtj !|| d|g}| js|"d|j#$dg d|j#$dg d|j#$dg f d}|"d|f |r$|"d|df | js$|"d|j%df t&j't(|t(|t(||d g|R   |D ]"}|j
t)  }|d*|+ }|d u rSq9|,|  q9|}t-|dkri|d }|S )Nz[The type of input in TranslatedLayer must be numpy array or Variable(Tensor), but received r@   FT)r   r+   r"   ZplaceZ	zero_copyc                 S      g | ]}|  qS r   r   rf   Zinsr   r   r   ri         z _run_dygraph.<locals>.<listcomp>zThe persistable variable z+ does not exist in current TranslatedLayer.)r   dimsr+   r   r"   r   r   r   r   ro   Z
program_idZx_namesZparam_grad_namesr   Zout_grad_namesr   Zx_grad_namesxuse_interpretorcoreZforward_global_blockZbackward_global_blockrW   ).rY   
isinstancenpZndarrayr   eagerTensor	TypeErrorr   r   r+   r   Z_current_expected_placer-   _input_args_namesr   _persistable_var_name_dict_parameters_buffersr   r   r   r   r   _is_testr   r   r~   r   r(   r)   r   utilsZ_hash_with_idr3   r   r   r   r   Zrun_programr  r   r   rN   Z_set_grad_typer[   )r   r   r   Z
input_varsZinput_var_namesr8   r   r:   r7   rc   Zdy_var_nameZoutput_varsr#   Ztmp_scope_vectrace_programr   r   r   r  Zpersistable_varr   Zgrad_varoutsr   r   r   _run_dygraphx  s   








r  c                 C   sd   t  }t|}t||d\}}|  t|||| | |  t|||}t|dkr0|d }|S )Nra   rW   r   )	r   Zdefault_main_programr;   rd   r_   _append_blockrm   _get_output_from_programr[   )r   r   r  Zmain_programparam_var_namesrV   rb   r  r   r   r   _run_static_graph  s(   
r  c                 C   sR   g }|dk r|S |  |jD ]}|| q|  |j}|dkr'|t| |7 }|S )z
    Get variables in current block and its parent block.

    Args:
        program(Program): The program containing the current block.
        block_idx(int): index of current block.

    Returns:
        List: list of variables.
    r   rX   )r(   r  r-   
parent_idx_collect_current_and_parent_var)r   r/   r  r:   r  r   r   r   r      s   r   c                 C   s  | j }t| |}t| ||d|d dd |jD }dd |D }t|t|kr;tdt| dt| dt|D ]\}	}
|rI||
 }
| |jd	d
||	 gid|
gid q?t	| ||d}| 
  | jd }d}| dkrtd| D ])}||}|j}|dkr|| }n|}| j|d}t|||d |t	||7 }q| 
  |D ]*}|dr|d}t|tjjr|j}t|tjr|j}|d| ||  q| 
  || _ dS )a,  
    Append Variables and Operators in 'src_program_desc' to dest_program.

    Args:
        dest_program(Program): Variables and Operators are appended to it.
        src_program_desc(ProgramDesc): Variables in it will be appended to 'dest_program'.
        program_holder(_ProgramHolder): program_holder of TranslatedLayer
        input_variables(list): list of input variables
        dict_rename_var_old_new(None|dict): When using '_rename_var_program_desc',
        use it to map the name of the variable before it was modified and the new name.
    r   r  c                 S   r  r   r   rf   inpr   r   r   ri   S  s    z!_append_block.<locals>.<listcomp>c                 S   s   g | ]}|j qS r   r   r!  r   r   r   ri   T  s    z)The number of input is invalid, expected z, but received r@   Zassignr   r   )r   r   r   rW   )r  Z	sub_blockN)Zcurrent_block_idxr   !append_var_from_block_desc_staticr(   r   r[   r   rY   	append_op append_op_from_block_desc_staticrm   r'   r&   parentZ_create_blockrp   attrr  r   r   Z	BlockDescidre   idxrq   )Zdest_programZsrc_program_descr   Zinput_variablesrb   Zorigin_block_idxr  Zname_inp_descZinput_namesr8   Zout_nameZ
append_opsZoffset_block_idxr  Zsrc_block_idxZ	src_blockZsrc_parent_idxZ
dest_blockr*   subZ	origin_idr   r   r   r  6  sr   






r  c           	      C   sf   g }|j D ]+}t| jD ]#}| |j}| }|r|| }||v r/|| }||vr/|| qq|S )zB
    Get output name of 'program' according to program_holder
    )r   r&   r'   r(   r  r+   r-   )	r   r   rb   r  r:   r)  r  rc   r   r   r   r   r    s   

	r  c                 C   s0   g }t | D ]}|t| || q|S )a  
    Append Operators of 'src_block_desc' to current block.

    Args:
        block(Block): append OP of  'src_block_desc' to it.
        src_block_desc(BlockDesc): append var of  'src_block_desc'

    Returns:
        List: list of the OP that are append to current block.
    )r&   r)   r-   append_op_from_desc_staticr*   )r(   src_block_descr   r8   r   r   r   r%    s   r%  c                 C   sB   |  }| j }|| tj| ||dddd}| j| |S )z
    Append Operators to 'block' according to 'op_desc'.

    Args:
        block(Block): append OP of  'src_block_desc' to it.
        op_desc(OpDesc): create OP according to it.

    Returns:
        Operator: OP appended to 'block'.
    N)r(   rk   r   r   r   r   )r   rk   r$  Z	copy_fromr   Operatorr   r-   )r(   Zop_descZop_typeZ	op_appendr*   r   r   r   r+    s   

r+  c                 C   s   g }|  D ]r}| }|du s||v o|du p||v}| |sx|rx| }|tjjjtjjjtjjj	fv r@|
 }	| }
nd}	d}
|tjjjtjjj	fv rU| }nd}| ra| j }n| }||j| |	||
|| | d q|S )a*  
    Append Variables of 'src_block_desc' to current block.
    If 'include' is not `None`,variables that are not in include are not append.
    If 'exclude' is not `None`,variables that are in exclude will are not append.

    Args:
        block(Block): append Variables of  'src_block_desc' to it.
        src_block_desc(BlockDesc): append var of  'src_block_desc'
        include(List):list of names of variables
        exclude(List):list of names of variables

    Returns:
        List: list of the variables that are append to current block.
    N)r+   r   r   r   	lod_levelr"   Zset_need_check_feed)r6   r+   r^   r   r   r    r!   ZSELECTED_ROWSr   ZDENSE_TENSOR_ARRAYr   r   r.  r"   r   r   r-   r   Zneed_check_feed)r(   r,  r`   ra   Zvars_appendr#   Zvar_desc_nameZshould_appendZvar_typeZ	data_typeZ	var_shaper.  Zcurrent_blockr   r   r   r#    sN   

r#  c                       sx   e Zd ZdZ fddZeejdddZedd Z	d	d
 Z
dd ZdddZdddZdddZdddZ  ZS )TranslatedLayeraO  
    TranslatedLayer is a ``paddle.nn.Layer`` for holding the model
    loaded by :ref:`api_paddle_jit_load` . It can be used like a
    general Layer object in eval or train mode.

    .. note:
        The TranslatedLayer objects should not be created by constructor, it only can be loaded and constructed by :ref:`api_paddle_jit_load` .

    Examples:
        .. code-block:: python

            >>> # doctest: +SKIP('`paddle.jit.to_static` can not run in xdoctest')
            >>> import numpy as np
            >>> import paddle
            >>> import paddle.nn as nn
            >>> import paddle.optimizer as opt

            >>> BATCH_SIZE = 16
            >>> BATCH_NUM = 4
            >>> EPOCH_NUM = 4

            >>> IMAGE_SIZE = 784
            >>> CLASS_NUM = 10

            >>> # define a random dataset
            >>> class RandomDataset(paddle.io.Dataset): # type: ignore[type-arg]
            ...     def __init__(self, num_samples):
            ...         self.num_samples = num_samples
            ...
            ...     def __getitem__(self, idx):
            ...         image = np.random.random([IMAGE_SIZE]).astype('float32')
            ...         label = np.random.randint(0, CLASS_NUM - 1, (1, )).astype('int64')
            ...         return image, label
            ...
            ...     def __len__(self):
            ...         return self.num_samples
            ...
            >>> class LinearNet(nn.Layer):
            ...     def __init__(self):
            ...         super().__init__()
            ...         self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM)
            ...
            ...     @paddle.jit.to_static
            ...     def forward(self, x):
            ...         return self._linear(x)
            ...
            >>> def train(layer, loader, loss_fn, opt):
            ...     for epoch_id in range(EPOCH_NUM):
            ...         for batch_id, (image, label) in enumerate(loader()):
            ...             out = layer(image)
            ...             loss = loss_fn(out, label)
            ...             loss.backward()
            ...             opt.step()
            ...             opt.clear_grad()
            ...             print("Epoch {} batch {}: loss = {}".format(
            ...                 epoch_id, batch_id, np.mean(loss.numpy())))
            ...
            >>> # 1. train & save model.
            >>> # create network
            >>> layer = LinearNet()
            >>> loss_fn = nn.CrossEntropyLoss()
            >>> adam = opt.Adam(learning_rate=0.001, parameters=layer.parameters())

            >>> # create data loader
            >>> dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
            >>> loader = paddle.io.DataLoader(dataset,
            ...     batch_size=BATCH_SIZE,
            ...     shuffle=True,
            ...     drop_last=True,
            ...     num_workers=2
            ... )
            >>> # train
            >>> train(layer, loader, loss_fn, adam)

            >>> # save
            >>> model_path = "linear.example.model"
            >>> paddle.jit.save(layer, model_path)

            >>> # 2. load model as TranslatedLayer
            >>> # load
            >>> translated_layer = paddle.jit.load(model_path)

            >>> # inference
            >>> translated_layer.eval()
            >>> x = paddle.randn([1, IMAGE_SIZE], 'float32')
            >>> pred = translated_layer(x)

            >>> # fine-tune
            >>> translated_layer.train()
            >>> adam = opt.Adam(learning_rate=0.001, parameters=translated_layer.parameters())
            >>> train(translated_layer, loader, loss_fn, adam)

    c                    s   t    t|tstdt|tstd|| _i | _t A |	 D ]4\}}t|t
jr@tt}|| j|< | || q&t|tjjrWtt}|| j|< | || q&tdW d    n1 sew   Y  d| _d | _d S )NzETranslatedLayer need to use _ProgramHolder's dict for initialization.zITranslatedLayer need to use persistable variable dict for initialization.z?Adding persistent variable which  to layer is not supported nowT)ru   rv   r  dictr  _program_holder_dictr  r   guardr   r   r   rJ   PARAMETER_NAME_PREFIXZadd_parameterr   r  r  BUFFER_NAME_PREFIXZregister_bufferr  r  )r   r  r7   r+   r:   Zdy_namer   r   r   rv   d  s8   


	



zTranslatedLayer.__init__Nc           	      C   s   t j| } t j| std|  dd }d }|d ur"|j}|j}t| |}t| ||}t	||}|
 D ]\}}|jd u rHdd |jD |_tt	|t	|| q6|  |S )NzThere is no directory named ''c                 S   r  r   r   r  r   r   r   ri     r  z.TranslatedLayer._construct.<locals>.<listcomp>)r   r   normpathisdirr   r   r   r   r  r/  r   r  r   setattr_execution_method_creatoreval)	r   Zconfigsr   r   r  r7   Ztranslated_layerr   r   r   r   r   
_construct  s6   


	zTranslatedLayer._constructc                    s    fdd |  _  S )Nc                    s@   | j  j }t rt| ||S tjt|j	}t
|||jS r2   )r1  r   r
   r  r   rj   Z_construct_from_descr   r   r   r  rk   )r   r   r   p__i_m_p_l__r   r   r>    s   
z>TranslatedLayer._execution_method_creator.<locals>.__i_m_p_l__)r   )r   r   r   r=  r   r9    s   z)TranslatedLayer._execution_method_creatorc                 C      d| _ d| _d S r%   r  Ztrainingr   r   r   r   train     
zTranslatedLayer.trainc                 C   r?  )NTFr@  r   r   r   r   r:    rB  zTranslatedLayer.evalr   c                 C   s   |  |}|j}t|}|S )aX  
        Gets translated program of specified method.

        Args:
            - method_name (string): method name corresponding to the program
                to be obtained. Default: 'forward'.

        Returns:
            Program

        Examples:
            .. code-block:: python

                >>> # doctest: +SKIP('`paddle.jit.to_static` can not run in xdoctest')
                >>> import numpy as np
                >>> import paddle
                >>> from paddle import nn
                >>> import paddle.optimizer as opt

                >>> BATCH_SIZE = 16
                >>> BATCH_NUM = 4
                >>> EPOCH_NUM = 4

                >>> IMAGE_SIZE = 784
                >>> CLASS_NUM = 10

                >>> # define a random dataset
                >>> class RandomDataset(paddle.io.Dataset): # type: ignore[type-arg]
                ...     def __init__(self, num_samples):
                ...         self.num_samples = num_samples
                ...
                ...     def __getitem__(self, idx):
                ...         image = np.random.random([IMAGE_SIZE]).astype('float32')
                ...         label = np.random.randint(0, CLASS_NUM - 1, (1, )).astype('int64')
                ...         return image, label
                ...
                ...     def __len__(self):
                ...         return self.num_samples
                ...
                >>> class LinearNet(nn.Layer):
                ...     def __init__(self):
                ...         super().__init__()
                ...         self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM)
                ...
                ...     @paddle.jit.to_static
                ...     def forward(self, x):
                ...         return self._linear(x)
                ...
                >>> def train(layer, loader, loss_fn, opt):
                ...     for epoch_id in range(EPOCH_NUM):
                ...         for batch_id, (image, label) in enumerate(loader()):
                ...             out = layer(image)
                ...             loss = loss_fn(out, label)
                ...             loss.backward()
                ...             opt.step()
                ...             opt.clear_grad()
                ...             print("Epoch {} batch {}: loss = {}".format(
                ...                 epoch_id, batch_id, np.mean(loss.numpy())))
                ...
                >>> # create network
                >>> layer = LinearNet()
                >>> loss_fn = nn.CrossEntropyLoss()
                >>> adam = opt.Adam(learning_rate=0.001, parameters=layer.parameters())
                >>> # create data loader
                >>> dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
                >>> loader = paddle.io.DataLoader(dataset,
                ...     batch_size=BATCH_SIZE,
                ...     shuffle=True,
                ...     drop_last=True,
                ...     num_workers=2
                ... )
                >>> # train
                >>> train(layer, loader, loss_fn, adam)

                >>> # save
                >>> model_path = "linear.example.model"
                >>> paddle.jit.save(layer, model_path)

                >>> # load
                >>> translated_layer = paddle.jit.load(model_path)

                >>> # get program
                >>> program = translated_layer.program()
        )_get_program_holderr   rn   )r   r   r   r   r   r   r   r   r     s   
VzTranslatedLayer.programc                 C   s*   | j |d }|d u rtd| d|S )NzThe method `z+` does not exist in loaded TranslatedLayer.)r1  r   r   )r   r   r   r   r   r   rC  4  s   
z#TranslatedLayer._get_program_holderc                 C   F   |  |}g }|jD ]}tjj| | | d}|| q
|S N)r   r   r+   )	rC  r   r   r   	InputSpecr   r   r+   r-   )r   r   r   Z
input_specr#   specr   r   r   _input_spec<  s   

zTranslatedLayer._input_specc                 C   rD  rE  )	rC  r   r   r   rF  r   r   r+   r-   )r   r   r   Zoutput_specr#   rG  r   r   r   _output_specL  s   

zTranslatedLayer._output_specr2   )r   )r   r   r   r   rv   staticmethodr   Zdygraph_onlyr;  r9  rA  r:  r   rC  rH  rI  r   r   r   r   r   r/    s    ^))


_
r/  )NNr2   )NT)Ar   r   numpyr  r   r   Zpaddle.baser   r   r   r   Zpaddle.base.data_feederr   Zpaddle.base.dygraph.baser   Zpaddle.base.frameworkr	   Zpaddle.frameworkr
   Z$paddle.jit.dy2static.partial_programr   r   Zpaddle.jit.dy2static.utilsr   Zpaddle.nn.layerr   __all__r   r   ZINFER_PARAMS_INFO_SUFFIXZINFER_PROPERTY_SUFFIXrA   r3  r4  r   r$   r1   r9   r;   r?   rF   rJ   rQ   rS   rU   rd   rn   rs   rt   r   r   r   r   r  r  r  r  r   r  r  r%  r+  r#  ZLayerr/  r   r   r   r   <module>   s   	




	 


  N
F<
0
. 
S

>