o
    Mee                    @   s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	m
Z
 d dlZd dlm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 d dlmZ d dlmZmZmZmZmZmZm Z m!Z! d d	l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z, d
dl-m.Z. d dl/m0Z0 d dl1m2Z2 d
dl3m4Z4 d
dl3m5Z5 d
dl4T d
dl3m6Z6 d
dl6T d
dl3m7Z7 ddl3m8Z9 d dl:m;Z; d dlm!Z! ej<Z<g de4j= Z=e2e>ej?ddZ@G dd deAZBG dd deBZCG dd deBZDd d! ZEd"d# ZFd$d% ZGd&d' ZHd(d) ZId*d+ ZJe d,d- ZKe d.d/ ZLd0d1 ZMe.dqd2d3ZNdrd4d5ZOe 				dsd6d7ZPe dtd8d9ZQd:d; ZRe dtd<d=ZS				dsd>d?ZTe dtd@dAZUe dtdBdCZVdrdDdEZW	FdudGdHZX	IdvdJdKZYe!e;dLdMdN				O	P	OdwdQdRZZe!e;dLdSdN			dqdTdUZ[dVdW Z\dXdY Z]drdZd[Z^d\d] Z_d^d_ Z`d`da Zadbdc Zbe!dxdddeZce!dydgdhZddidj Zee!dtdkdlZfdrdmdnZge!dodp ZhdS )z    )print_functionN)reduce)BytesIO)layers)Executorglobal_scope)	Evaluator)Program	Parameterdefault_main_programdefault_startup_programVariableprogram_guarddygraph_not_supportstatic_only)
cachemap_readersbufferedcomposechainshuffleComposeNotAlignedfirstnxmap_readersmultiprocess_reader   )signature_safe_contextmanager)CompiledProgram)
get_logger)reader)unique_name)*)
dataloader)core   )compat)
deprecated)r   )	save_varssave_paramssave_persistables	load_varsload_paramsload_persistablessave_inference_modelload_inference_modelbatchsaveloadload_program_stateset_program_stateget_program_parameterget_program_persistable_varsz&%(asctime)s-%(levelname)s: %(message)s)fmtc                   @   s   e Zd Zdd Zdd ZdS )_open_bufferc                 C   s
   || _ d S Nbufferselfr:    r=   ?D:\Projects\ConvertPro\env\Lib\site-packages\paddle/fluid/io.py__init__N      
z_open_buffer.__init__c                 C   s   | j S r8   r9   )r<   r=   r=   r>   	__enter__Q   s   z_open_buffer.__enter__N)__name__
__module____qualname__r?   rA   r=   r=   r=   r>   r7   L   s    r7   c                       s$   e Zd Z fddZdd Z  ZS )_buffer_readerc                    s    t t| | | j | _d S r8   )superrE   r?   r:   tellinitial_tellr;   	__class__r=   r>   r?   W   s   z_buffer_reader.__init__c                 G   s"   |d d ur| j | j d S d S )Nr   )r:   seekrH   r<   argsr=   r=   r>   __exit__[   s   z_buffer_reader.__exit__)rB   rC   rD   r?   rN   __classcell__r=   r=   rI   r>   rE   U   s    rE   c                   @   s   e Zd Zdd ZdS )_buffer_writerc                 G   s   | j   d S r8   )r:   flushrL   r=   r=   r>   rN   c   s   z_buffer_writer.__exit__N)rB   rC   rD   rN   r=   r=   r=   r>   rP   a   s    rP   c                 C   
   t | tS r8   )
isinstancestr)pathr=   r=   r>   _is_file_pathg   r@   rV   c                 C   s@   t | r	t| |S d|v rt| S d|v rt| S td|)Nwrz&Expected 'r' or 'w' in mode but got {})rV   openrP   rE   
ValueErrorformat)Zpath_or_buffermoder=   r=   r>   _open_file_bufferk   s   
r]   c                 C   rR   r8   )rS   r   r9   r=   r=   r>   _is_memory_buffery   r@   r^   c                 C   rR   )a  
    Check whether the given variable is an instance of Parameter.

    Args:
        var(Variable): The variable to be checked.

    Returns:
        bool: True if the given `var` is an instance of Parameter,
        False if not.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            param = fluid.default_main_program().global_block().var('fc.w')
            res = fluid.io.is_parameter(param)
    )rS   r
   varr=   r=   r>   is_parameter}   s   
ra   c                 C   sF   | j  tjjjks| j  tjjjks| j  tjjjkr dS | jS )a  
    Check whether the given variable is persistable.

    Args:
        var(Variable): The variable to be checked.

    Returns:
        bool: True if the given `var` is persistable
        False if not.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            param = fluid.default_main_program().global_block().var('fc.b')
            res = fluid.io.is_persistable(param)
    F)	desctyper#   VarDescVarTypeFEED_MINIBATCH
FETCH_LISTREADERpersistabler_   r=   r=   r>   is_persistable   s
   rj   c                 C   s    t | ts| j st| S dS NF)rS   r
   rb   Zneed_check_feedrj   r_   r=   r=   r>   is_belong_to_optimizer   s   rl   c                 C      t tt|  S )a  
    Get all the parameters from Program.

    Args:
        var(Program): The Program to get parameters

    Returns:
        list: The list contains all parameters in the program

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            data = fluid.data(name="img", shape=[64, 784])
            w = fluid.layers.create_parameter(shape=[784, 200], dtype='float32', name='fc_w')
            b = fluid.layers.create_parameter(shape=[200], dtype='float32', name='fc_b')
            list_para  = fluid.io.get_program_parameter(  fluid.default_main_program() )
    )listfilterra   	list_varsprogramr=   r=   r>   r4         r4   c                 C   rm   )a  
    Get all the persistable vars from Program.

    Args:
        var(Program): The Program to get persistable vars

    Returns:
        list: The list contains all persistable vars in the program

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            data = fluid.data(name="img", shape=[64, 784])
            w = fluid.layers.create_parameter(shape=[784, 200], dtype='float32', name='fc_w')
            b = fluid.layers.create_parameter(shape=[200], dtype='float32', name='fc_b')
            list_para  = fluid.io.get_program_persistable_vars(  fluid.default_main_program() )
    )rn   ro   rj   rp   rq   r=   r=   r>   r5      rs   r5   c                 C   s^   t |tsJ |j tjjjkr!| j|j	|j
|j|j|jddS | j|j	|j
|j|jddS )NTnameshapedtyperc   	lod_levelri   )ru   rv   rw   rc   ri   )rS   r   rb   rc   r#   rd   re   
LOD_TENSOR
create_varru   rv   rw   rx   blockr`   r=   r=   r>   _clone_var_in_block_   s   r}   c                 c   s
   | r| nt j }|r|nt j }|r|nt jj }t j|X t j||8 t jj " t jj	
d  d V  W d    n1 sHw   Y  W d    n1 sWw   Y  W d    n1 sfw   Y  W d    d S W d    d S 1 s~w   Y  d S r8   )paddlefluidr	   r#   ZScopeZscope_guardr   r    guardZ	frameworkZ_dygraph_guard)mainZstartupscopeprogZstartup_progr=   r=   r>   _load_program_scope   s"   "r   c                 C   sX   | d u rt  } nt| tr| j} | d u rtdtd t| ts*tdt|  | S )NzVThe type of input main_program is invalid, expected tyep is Program, but received Nonez8The input is a CompiledProgram, this is not recommended.ZThe type of input main_program is invalid, expected type is fluid.Program, but received %s)	r   rS   r   Z_program	TypeErrorwarningswarnr	   rc   )main_programr=   r=   r>   _get_valid_program	  s$   

r   c              	   C   s  d}|du r|du rd}t |}|du r$t| ||tt|| |dS d}tt|dkr5td dS t }|	 }	i }
|D ]<}|j
tjjjkrKq@t|	|}|du rw|du rwtjtj||j}|	jdd	|gii d
tj|id q@||
|j< q@|dus|rg }t|
 D ]	}||
|  qt }|du rtjtj||}|	jtjjj|d}|jd |	jdd	|id|i||dd |  | | |rt  |! S dS )a  
    Save specific variables in the `Program` to files.

    There are two ways to specify the variables to be saved: set variables in
    a list and assign it to the `vars`, or use the `predicate` function to select
    variables that make `predicate(variable) == True`. The first way has a higher priority.

    The `dirname` is used to specify the folder where to save variables.
    If you prefer to save variables in separate files in the `dirname` folder,
    do not set `filename`. If you prefer to save all variables in a single file,
    use `filename` to specify it.

    Args:
        executor(Executor): The executor to run for saving variables.
        dirname(str, optional): The folder where to save variables.
                            When you need to save the parameter to the memory, set it to None.
        main_program(Program, optional): The program whose variables will be saved.
                                    If it is None, the default main program will
                                    be used automatically.
                                    Default: None
        vars(list[Variable], optional): The list contains all variables to be saved.
                                        Default: None
        predicate(function, optional): The function selects the variables that make
                                       `predicate(variable) == True`.
                                       Default: None
        filename(str, optional): If you prefer to save all variables in a single file,
                                 use `filename` to specify it. Otherwise, let `filename` be None.
                                 Default: None

    Returns:
        str: When saving parameters to a file, returns None.
             When saving parameters to memory, returns a binary string containing parameters.

    Raises:
        TypeError: If `main_program` is not an instance of Program nor None.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            main_prog = fluid.Program()
            startup_prog = fluid.Program()
            with fluid.program_guard(main_prog, startup_prog):
                data = fluid.layers.data(name="img", shape=[64, 784], append_batch_size=False)
                w = fluid.layers.create_parameter(shape=[784, 200], dtype='float32', name='fc_w')
                b = fluid.layers.create_parameter(shape=[200], dtype='float32', name='fc_b')
                hidden_w = fluid.layers.matmul(x=data, y=w)
                hidden_b = fluid.layers.elementwise_add(hidden_w, b)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(startup_prog)

            # The first usage: use `vars` to set the saved variables.
            var_list = [w, b]
            path = "./my_paddle_vars"
            fluid.io.save_vars(executor=exe, dirname=path, vars=var_list,
                            filename="vars_file")
            # w and b will be save in a file named "var_file".

            # The second usage: use `predicate` to select the saved variable.
            def name_has_fc(var):
                res = "fc" in var.name
                return res
            param_path = "./my_paddle_model"
            fluid.io.save_vars(executor=exe, dirname=param_path, main_program=main_prog, vars=None, predicate = name_has_fc)
            # all variables whose names contain "fc " are saved.
    FNT)r   dirnamevarsfilenamesaved_paramsr   zVno variable in your model, please ensure there are any variables in your model to saver0   X	file_pathrc   inputsZoutputsattrs)rc   ru   Zsave_combineY)r   save_to_memory)"r   r'   rn   ro   rp   lenr   r   r	   global_blockrc   r#   rd   re   RAWr}   osrU   joinnormpathru   	append_opsortedkeysappendrT   rz   rb   Zset_persistable_sync_with_cpprunr   find_var	get_bytes)executorr   r   r   	predicater   r   Zparams_var_nameZsave_programZ
save_blockZsave_var_mapeach_varnew_varZsave_file_pathZsave_var_listru   Z	save_pathr   r=   r=   r>   r'     st   M

r'   c                 C   s   t | ||dt|dS )ab  
    Save all parameters from the :code:`main_program` to
    the folder :code:`dirname` or file :code:`filename`. You can refer to
    :ref:`api_guide_model_save_reader_en` for more details.

    Use the :code:`dirname` to specify the saving folder. If you would like to
    save parameters in separate files, set :code:`filename` None; if you would
    like to save all parameters in a single file, use :code:`filename` to specify
    the file name.

    Note:
        Some variables are not Parameter while they are necessary for
        training, such as learning rate, global step, etc. So you can NOT save
        and continue your training just by :ref:`api_fluid_io_save_params`
        and :ref:`api_fluid_io_load_params`. Please use :ref:`api_fluid_io_save_persistables`
        and :ref:`api_fluid_io_load_persistables` instead.

        If you want to save your model for the inference, please use the
        :ref:`api_fluid_io_save_inference_model`. You can refer to
        :ref:`api_guide_model_save_reader_en` for more details.

    Args:
        executor(Executor): The executor to run for saving parameters, You can
                            refer to :ref:`api_guide_executor_en`.
        dirname(str, optional): The saving directory path.
                            When you need to save the parameter to the memory, set it to None.
        main_program(Program, optional): The program whose parameters will be
                                         saved. You can refer to
                                         :ref:`api_guide_Program_en` for more
                                         details. If it is None, the default main
                                         program will be used.
                                         Default: None
        filename(str, optional): The file to save all parameters. If you prefer
                                 to save parameters in different files, set it
                                 to None.
                                 Default: None

    Returns:
        str: When saving parameters to a file, returns None.
             When saving parameters to memory, returns a binary string containing parameters.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid


            paddle.enable_static()
            params_path = "./my_paddle_model"
            image = fluid.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = fluid.data(name='label', shape=[None, 1], dtype='int64')
            feeder = fluid.DataFeeder(feed_list=[image, label], place=fluid.CPUPlace())
            predict = fluid.layers.fc(input=image, size=10, act='softmax')

            loss = fluid.layers.cross_entropy(input=predict, label=label)
            avg_loss = paddle.mean(loss)

            exe = fluid.Executor(fluid.CPUPlace())
            exe.run(fluid.default_startup_program())
            fluid.io.save_params(executor=exe, dirname=params_path)
            # The parameters weights and bias of the fc layer in the network are going to
            # be saved in different files in the path "./my_paddle_model"
    Nr   r   r   r   r   )r'   ra   r   r   r   r   r=   r=   r>   r(     s   Br(   c           	      C   s   dd }dd }g fdd}t |tstd|jstd|jjd	d
gdd}g }|r3||  |j	rIt |j	t
rC||j	 n||j	 t
t||| }t| |||d |jru|rg|| || |j	rw|| ||j	|j dS dS dS )a  
    save_persistables for distributed training.
    the method will do things listed below:
    1.save part of persistable variables on trainer.
    2.receive "remote prefetch variables" from parameter servers and merge them.
    3.save "distributed lookup table" on parameter servers.
    4.receive "optimizer variables" from parameter servers and merge them.

    Args:
        executor(Executor): The executor to run for saving parameters.
        dirname(str): The saving directory path.
        main_program(Program): The program whose parameters will be
                            saved. the main_program must be the trainer_program
                            get after transpiler.

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            param_path = "./my_paddle_model"
            t = distribute_transpiler.DistributeTranspiler()
            t.transpile(...)
            train_program = t.get_trainer_program()
            _save_distributed_persistables(executor=exe, dirname=param_path, main_program=train_program)
    c                 S   s8  |sdS t  }| }| D ]\}}|d j}|d j}dgt| }	dgt| }
dgt| }dgt| }t|D ])\}}|j}|j}|j	}|rN|n|}||	|< d
|j||
|< |j||< |||< q=g }|	D ]}dd |jD }|d| qk|jdd|j||
||tj||jdd	 q| | dS )
z
        receive params on pserver through rpc.
        if the params are be sliced, will concat them to one, then save it.
        Nr   z{}.slice.{}c                 S   s   g | ]}t |qS r=   )rT   ).0dimr=   r=   r>   
<listcomp><      zP_save_distributed_persistables.<locals>.__save_remote_params.<locals>.<listcomp>,Z	recv_save)Z
trainer_idrv   slice_shapesslice_varnamesremote_varnames	endpointsr   )rc   r   )r	   r   itemsoriginis_slicer   	enumerateblock_idsliceendpointr[   ru   rv   r   r   r   r   rU   r   )r   r   remote_params_mapr   r|   ru   Zremote_paramsr   r   slicesr   r   r   idxZ	optimizerr   r   r   indexr   tmpr=   r=   r>   __save_remote_params  sF   



z<_save_distributed_persistables.<locals>.__save_remote_paramsc                 S   sX   t  }| }tj|d}i }||d< ||d< ||d< |jdi i |d | | dS )z
        because the distributed lookup table may too huge to merge and save at one place,
        it will be saved at parameter server independent respectively.

        the save directory is dirname/"__lookup_table__".

        Z__lookup_table__epmapdirZlookup_tableZcheckpoint_notifyr   N)r	   r   r   rU   r   r   r   )r   r   Zdistributed_lookup_tabler   r   r|   Zlookup_table_filenamer   r=   r=   r>    __save_distributed_lookup_tablesL  s   	zH_save_distributed_persistables.<locals>.__save_distributed_lookup_tablesc                    s    fdd}|S )Nc                    sT   | j  v rdS | j tjjjks%| j tjjjks%| j tjjjkr'dS | j	S rk   )
ru   rb   rc   r#   rd   re   rf   rg   rh   ri   r_   exclude_var_namesr=   r>   is_validf  s   
zH_save_distributed_persistables.<locals>.__exclude_vars.<locals>.is_validr=   )r   r   r=   r   r>   __exclude_varsd  s   	z6_save_distributed_persistables.<locals>.__exclude_vars0'main_program' should be an instance of Program.zK'_save_distributed_persistables' just be designed for distributed training.Z	OptimizerZRemotePrefetchT)groupby)r   r   r   N)rS   r	   r   _is_distributedrZ   _parameters_on_pserversZget_distributed_vars_by_vtypesextendr   Z_distributed_lookup_tablern   r   ro   rp   r'   Z	_is_chiefZ
_endpoints)	r   r   r   r   r   r   r   r   
local_varsr=   r=   r>   _save_distributed_persistables  sJ   "2
r   c                 C   s,   |r|j rt| ||dS t| ||dt|dS )a=  
    Save all persistable variables from :code:`main_program` to 
    the folder :code:`dirname` or file :code:`filename`. You can refer to 
    :ref:`api_guide_model_save_reader_en` for more details. And then
    saves these persistables variables to the folder :code:`dirname` or file
    :code:`filename`.

    The :code:`dirname` is used to specify the folder where persistable variables
    are going to be saved. If you would like to save variables in separate
    files, set :code:`filename` None; if you would like to save all variables in a
    single file, use :code:`filename` to specify the file name.

    Args:
        executor(Executor): The executor to run for saving persistable variables.
                            You can refer to :ref:`api_guide_executor_en` for
                            more details.

        dirname(str, optional): The saving directory path.
                            When you need to save the parameter to the memory, set it to None.
        main_program(Program, optional): The program whose persistbale variables will
                                         be saved. You can refer to 
                                         :ref:`api_guide_Program_en` for more details.
                                         If it is None, the default main program will
                                         be used.
                                         Default: None.
        filename(str, optional): The file to save all variables. If you prefer to
                                 save variables in different files, set it to None.
                                 Default: None.

    Returns:
        str: When saving parameters to a file, returns None.
             When saving parameters to memory, returns a binary string containing parameters.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            dir_path = "./my_paddle_model"
            file_name = "persistables"
            image = fluid.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = fluid.data(name='label', shape=[None, 1], dtype='int64')
            feeder = fluid.DataFeeder(feed_list=[image, label], place=fluid.CPUPlace())

            predict = fluid.layers.fc(input=image, size=10, act='softmax')
            loss = fluid.layers.cross_entropy(input=predict, label=label)
            avg_loss = paddle.mean(loss)
            exe = fluid.Executor(fluid.CPUPlace())
            exe.run(fluid.default_startup_program())
            fluid.io.save_persistables(executor=exe, dirname=dir_path, filename=file_name)
            # The persistables variables weights and bias in the fc layer of the network
            # are going to be saved in the same file named "persistables" in the path
            # "./my_paddle_model"
    r   r   Nr   )r   r   r'   rj   r   r=   r=   r>   r)     s   
:r)   c              
   C   s  d}|durt j|}nd}|du r9|du rt }t|ts'tdt| t| ||t	t
|| |d dS t }| }|du rGt }t|tsTtdt| i }	i }
g }g }|D ]_}t|tsgJ |jtjjjkrpq^t|trt|j |	|j< |jtjjjkr|| q^t||}|| |du r|du rtd|jdi d|gid	t j||jid
 q^||
|j< q^|D ]}t|tsJ |durtdt||}t j||j}t j|std|j|t j|r	|jdi d|gid	t j||jid
 qg }t  |}|D ]}|!|jr || qg }|D ]+}|j"||j|j#|j$dd}|| t j||d}|jdi d|gid	|id
 q&|jdd|id|ii d
 q|durg }t%|
& D ]
}||
|  qm|du rt j||}|jdi d|i||dd
 | '| |D ]J}t|tsqt(j)* +|j}|dksJ d|j t,-|. j#}|j|	v sJ |jd |	/|j}||krt0d||j|qdS )aq  
    :api_attr: Static Graph

    This API loads variables from files by executor.

    There are two ways to specify the variables to be loaded: the first way, set
    variables in a list and assign it to the `vars`; the second way, use the
    `predicate` function to select variables that make `predicate(variable) == True`.
    The first way has a higher priority.

    The `dirname` is used to specify the folder where to load variables.
    If variables were saved in separate files in the folder `dirname`,
    set `filename` None. If all variables were saved in a single file,
    use `filename` to specify it.

    Args:
        executor(Executor): The executor to run for loading variables.
        dirname(str): The folder where to load the variables.
        main_program(Program, optional): The program whose variables will be loaded.
                                    If it is None, the default main program will
                                    be used automatically.
                                    Default: None
        vars(list[Variable], optional): The list that contains all variables to be loaded.
                                   Default: None
        predicate(function, optional): The function selects variables that make
                                        `predicate(variable) == True`.
                                        Default: None
        filename(str, optional): The file which saved all required variables. If variables
                                were saved in separate files, set it to be None.
                                Default: None

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            main_prog = fluid.Program()
            startup_prog = fluid.Program()
            with fluid.program_guard(main_prog, startup_prog):
                data = fluid.layers.data(name="img", shape=[64, 784], append_batch_size=False)
                w = fluid.layers.create_parameter(shape=[784, 200], dtype='float32', name='fc_w')
                b = fluid.layers.create_parameter(shape=[200], dtype='float32', name='fc_b')
                hidden_w = fluid.layers.matmul(x=data, y=w)
                hidden_b = fluid.layers.elementwise_add(hidden_w, b)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(startup_prog)

            # The first usage: using `vars` to specify the variables.
            path = "./my_paddle_vars"
            var_list = [w, b]
            fluid.io.save_vars(executor=exe, dirname=path, vars=var_list,
                               filename="vars_file")
            fluid.io.load_vars(executor=exe, dirname=path, vars=var_list,
                               filename="vars_file")
            # w and b will be loaded, and they are supposed to
            # be saved in the same file named 'var_file' in the path "./my_paddle_vars".

            # The second usage: using the `predicate` function to select variables
            param_path = "./my_paddle_model"
            def name_has_fc(var):
                res = "fc" in var.name
                return res
            fluid.io.save_vars(executor=exe, dirname=param_path, main_program=main_prog,
                              vars=None, predicate=name_has_fc)
            fluid.io.load_vars(executor=exe, dirname=param_path, main_program=main_prog,
                               vars=None, predicate=name_has_fc)
            # Load All variables in the `main_program` whose name includes "fc".
            # And all the variables are supposed to be saved in separate files.

    FNTr   )r   r   r   r   z>The directory path and params cannot be None at the same time.r1   Outr   r   z.SelectedRows can not be load with load_combinez&SelectedRows var {} can not find at {}ru   rc   rv   rw   ri   ParamZlookup_sparse_table_merger   Zload_combine)r   Zmodel_from_memoryzcan't not find var: zMUST in var listzVariable's shape does not match, the Program requires a parameter with the shape of ({}), while the loaded parameter (namely [ {} ]) has a shape of  ({}).)1r   rU   r   r   rS   r	   r   rc   r*   rn   ro   rp   r   r   r#   rd   re   r   r
   tuplerb   	get_shaperu   ZSELECTED_ROWSr   r}   rZ   r   r   existsr[   isfilelistdir
startswithrz   rv   rw   r   r   r   r~   r   r   r   nparray
get_tensorgetRuntimeError)r   r   r   r   r   r   Zvars_from_memory	load_prog
load_blockZorig_para_shapeZload_var_mapZ
check_varsZsparse_varsr   r   var_pathblocksZblock_pathsr|   r   r   r   Zload_var_listru   var_tempZ	new_shapeZ
orig_shaper=   r=   r>   r*     s  R
















r*   c                 C   s   t | ||t|d dS )a:	  
    :api_attr: Static Graph

    This API filters out all parameters from the give ``main_program``
    and then tries to load these parameters from the directory ``dirname`` or
    the file ``filename``.

    Use the ``dirname`` to specify the directory where parameters were saved. If
    parameters were saved in separate files under the directory `dirname`, set
    ``filename`` as None; if all parameters were saved in a single file, use
    ``filename`` to specify the file name.

    **Note**:
        Some variables are not Parameter while they are necessary for
        training, such as learning rate, global step, etc. So you cannot save and
        continue your training just by using :ref:`api_fluid_io_save_params` and
        :ref:`api_fluid_io_load_params`. Please use :ref:`api_fluid_io_save_persistables`
        and :ref:`api_fluid_io_load_persistables` instead.

        If you want to load the pre-trained model structure and parameters
        for the inference, please use the :ref:`api_fluid_io_load_inference_model` API. You can
        refer to :ref:`api_guide_model_save_reader_en` for more details.

    Args:
        executor(Executor): The executor used for loading parameters.
                            See :ref:`api_guide_executor_en` for more details about it.
        dirname(str): The directory path.
        main_program(Program, optional): The program whose parameters will be
                                    loaded. If it is None, the ``default_main_program``
                                    will be used automatically. See :ref:`api_guide_Program_en`
                                    for more about ``Program``.
                                    Default: None.
        filename(str, optional): The file which saved all parameters. If parameters
                            were saved in separated files, set it to None.
                            Default: None.

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            param_path = "./my_paddle_model"
            prog = fluid.default_main_program()
            fluid.io.load_params(executor=exe, dirname=param_path,
                                main_program=None)
    r   r   r   r   N)r*   ra   r   r=   r=   r>   r+     s   6
r+   c                 C   s2   |r|j rt| ||d dS t| ||t|d dS )a%  
    :api_attr: Static Graph

    This API filters out all variables with ``persistable==True`` from the
    given ``main_program`` and then tries to load these variables from the
    directory ``dirname`` or the file ``filename``.

    Use the ``dirname`` to specify the directory where persistable variables
    (refer to :ref:`api_guide_model_save_reader_en`) were saved. If variables
    were saved in separate files, set ``filename`` as None; if all variables
    were saved in a single file, use ``filename`` to specify the file name.

    Args:
        executor(Executor): The executor used for loading persistable variables.
                            See :ref:`api_guide_executor_en` for more details about it.
        dirname(str): The directory path.
        main_program(Program, optional): The program whose persistable variables will
                                    be loaded. If it is None, the ``default_main_program``
                                    will be used automatically. See :ref:`api_guide_Program_en`
                                    for more about ``Program``.
                                    Default: None.
        filename(str, optional): The file which saved all persistable variables. If variables
                                 were saved in separated files, set it to None.
                                 Default: None.

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            param_path = "./my_paddle_model"
            prog = fluid.default_main_program()
            fluid.io.load_persistables(executor=exe, dirname=param_path,
                                       main_program=None)
    r   r   N)r   _load_distributed_persistablesr*   rj   r   r=   r=   r>   r,     s   
,

r,   c                 C   s\   dd }dd }t |tstd|jstd|jstd|j|j}|| || dS )	a  
    customized load_persistables for distributed training.
    it should be used on parameter server,

    Args:
        executor(Executor): The executor to run for saving parameters.
        dirname(str): The load directory path.
        main_program(Program): The program whose parameters will be
                            loaded. the main_program must be the pserver_program
                            get after transpiler.

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            param_path = "./my_paddle_model"
            t = distribute_transpiler.DistributeTranspiler()
            t.transpile(...)
            pserver_prog = t.get_pserver_program(...)
            _load_distributed_persistables(executor=exe, dirname=param_path, main_program=pserver_prog)
    c                 S   s   |  d}|  d}|p|S )Nz	.trainer_z.block)find)varnameZtrainer_idxZ	block_idxr=   r=   r>   __is_distributed_part_varX  s   

zA_load_distributed_persistables.<locals>.__is_distributed_part_varc              
   S   s   t  }| }g }|D ][}|j}|j}|j}	|j}
|	rA|j|j|j|j	|j
dd}|jdi d|gitj||j|
|j	dd q|jd|j|j|j	|j
dd}|jdi d|gidtj||jid q|jd	d
|id | | d S )NTr   r1   r   )r   rK   rv   r   z{}r   Z
delete_varr   )rc   r   )r	   r   r   r   r   offsetrz   ru   rc   rv   rw   r   r   rU   r   r[   r   )r   r   need_load_varsr   r   Zneed_delete_varsparamZ
origin_varZ	slice_varr   r   r   r   r=   r=   r>   __load_persistable_vars]  sT   z?_load_distributed_persistables.<locals>.__load_persistable_varsr   zK'_load_distributed_persistables' just be designed for distributed training.z\'_load_distributed_persistables' need current_endpoint set in DistributeTranspiler.transpileN)rS   r	   r   r   rZ   Z_ps_endpointr   Zget_distributed_vars_by_ep)r   r   r   r   r   r   r=   r=   r>   r   :  s    
1r   feedc                 C   s   t |dkrd S |  }|j|tjjjdd}t|D ](\}}||s-t	dj
||d||}|jdd|gid|gid	|id
 qd S )Nr   Tru   rc   ri   zThe feeded_var_names[{i}]: '{name}' doesn't exist in pruned inference program. Please check whether '{name}' is a valid feed_var name, or remove it from feeded_var_names if '{name}' is not involved in the target_vars calculation.)iru   r   r   r   colr   )r   r   rz   r#   rd   re   rf   r   has_varrZ   r[   r`   Z_prepend_op)inference_programfeed_target_namesZfeed_holder_namer   Zfeed_varr   ru   outr=   r=   r>   prepend_feed_ops  s*   

r   fetchc                 C   sV   |   }|j|tjjjdd}t|D ]\}}|jdd|gid|gid|id qd S )NTr   r   r   r   r   r   )r   rz   r#   rd   re   rg   r   r   )r   fetch_target_namesZfetch_holder_namer   Z	fetch_varr   ru   r=   r=   r>   append_fetch_ops  s   r   z2.0.0z"paddle.static.save_inference_model)ZsinceZ	update_toTFc
              
   C   s  t |tjr
|g}n|r#t|dkr#t|rtdd |D s#tdt |tr,|g}n|r?t|r;tdd |D s?tdt|}|	 j
}
|
D ]}tj }||d |jdkrctd	  nqJt| g }t|D ]	\}}|| qo|}W d
   n1 sw   Y  dd |D }| }ztj| }t| W n ty } z|jtjkr W Y d
}~nd
}~ww |d
urtj|}nd}tj||}| }|r| }|	 }g }t|j
D ]\}}|j d |jdks|jdkr|| q|d
d
d D ]}|!| q|j"  |j#||d}|j$dd}dd |D }|D ]}|	 %|j&sC|	 j'|j&|j(|j)|j*d q)t+|| t,|| |j-  t.j/j0|j t1|d}|2|j3|	dj4  W d
   n	1 syw   Y  n$t1|d d}|2|j3|	dj4  W d
   n	1 sw   Y  |rtd |S |5| |d
urtj|}t6|||| |S )a  
    Prune the given `main_program` to build a new program especially for inference,
    and then save it and all related parameters to given `dirname` .
    If you just want to save parameters of your trained model, please use the
    :ref:`api_fluid_io_save_params` . You can refer to :ref:`api_guide_model_save_reader_en`
    for more details.

    Note:
        The :code:`dirname` is used to specify the folder where inference model
        structure and parameters are going to be saved. If you would like to save params of
        Program in separate files, set `params_filename` None; if you would like to save all
        params of Program in a single file, use `params_filename` to specify the file name.

    Args:
        dirname(str): The directory path to save the inference model.
        feeded_var_names(list[str]): list of string. Names of variables that need to be fed
                                     data during inference.
        target_vars(list[Variable]): list of Variable. Variables from which we can get
                                     inference results.
        executor(Executor): The executor that saves the inference model. You can refer
                            to :ref:`api_guide_executor_en` for more details.
        main_program(Program, optional): The original program, which will be pruned to
                                         build the inference model. If is set None,
                                         the global default :code:`_main_program_` will be used.
                                         Default: None.
        model_filename(str, optional): The name of file to save the inference program
                                       itself. If is set None, a default filename
                                       :code:`__model__` will be used.
        params_filename(str, optional): The name of file to save all related parameters.
                                        If it is set None, parameters will be saved
                                        in separate files .
        export_for_deployment(bool, optional): If True, programs are modified to only support
                                     direct inference deployment. Otherwise,
                                     more information will be stored for flexible
                                     optimization and re-training. Currently, only
                                     True is supported.
                                     Default: True.
        program_only(bool, optional): If True, It will save inference program only, and do not
                                      save params of Program.
                                      Default: False.

    Returns:
        list, The fetch variables' name list.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            path = "./infer_model"

            # User defined network, here a softmax regession example
            image = fluid.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = fluid.data(name='label', shape=[None, 1], dtype='int64')
            feeder = fluid.DataFeeder(feed_list=[image, label], place=fluid.CPUPlace())
            predict = fluid.layers.fc(input=image, size=10, act='softmax')

            loss = fluid.layers.cross_entropy(input=predict, label=label)
            avg_loss = paddle.mean(loss)

            exe = fluid.Executor(fluid.CPUPlace())
            exe.run(fluid.default_startup_program())

            # Feed data and train process

            # Save inference model. Note we don't save label and loss in this example
            fluid.io.save_inference_model(dirname=path,
                                          feeded_var_names=['img'],
                                          target_vars=[predict],
                                          executor=exe)

            # In this example, the save_inference_mode inference will prune the default
            # main program according to the network's input node (img) and output node(predict).
            # The pruned inference program is going to be saved in the "./infer_model/__model__"
            # and parameters are going to be saved in separate files under folder
            # "./infer_model".

    r   c                 s   s    | ]	}t |tjV  qd S r8   )rS   sixstring_typesr   ru   r=   r=   r>   	<genexpr>)  s
    

z'save_inference_model.<locals>.<genexpr>z)'feed_var_names' should be a list of str.c                 s   s    | ]}t |tV  qd S r8   )rS   r   r   r`   r=   r=   r>   r   2  s    z+'target_vars' should be a list of Variable. ZauczUplease ensure that you have set the auc states to zeros before saving inference modelNc                 S      g | ]}|j qS r=   ru   r   r=   r=   r>   r   H      z(save_inference_model.<locals>.<listcomp>	__model__Fr   r   )feeded_var_namestargetsT)Zprune_read_opc                 S   r   r=   r   )r   vr=   r=   r>   r   q  r   )ru   rv   rw   ri   wb)
clip_extraz.main_programzdsave_inference_model specified the param `program_only` to True, It will not save params of Program.)7rS   r   r   r   boolallrZ   r   r   r   opsr#   Zop_proto_and_checker_makerZkOpDeviceAttrNameZ	_set_attrrc   r   r   r   r   r   r   rU   r   makedirsOSErrorerrnoEEXISTbasenamer   clonerb   Zset_is_targetZ
_remove_oprQ   Z_prune_with_inputZ_inference_optimizer   ru   rz   rv   rw   ri   r   r   _set_versionr~   r   save_op_version_inforY   writeZ_remove_training_infoserialize_to_stringZ_copy_dist_param_info_fromr)   )r   r  Ztarget_varsr   r   model_filenameparams_filenameZexport_for_deploymentZprogram_onlyr  Zall_opsopZdevice_attr_nameZuniq_target_varsr   r`   Ztarget_var_name_listZsave_dirnameeZmodel_basenameZorigin_programr   Zneed_to_remove_op_indexr   Zfetch_var_namesZtarget_vfr=   r=   r>   r-     s   \











r-   z"paddle.static.load_inference_modelc                    s.  d}| durMt j| }t j|std|  |du rd}t j|t j|}|dur3t j|}t|d}| }W d   n1 sGw   Y  nd}|du rWtd| }|}|}t	
| t  sqtd   t|| | |rt |  j }	 j }
 fd	d
|
D } |	|gS )a(  
    Load the inference model from a given directory. By this API, you can get the model
    structure(Inference Program) and model parameters. If you just want to load
    parameters of the pre-trained model, please use the :ref:`api_fluid_io_load_params` API.
    You can refer to :ref:`api_guide_model_save_reader_en` for more details.

    Args:
        dirname(str): One of the following:
          - The given directory path.
          - Set to None when reading the model from memory.
        executor(Executor): The executor to run for loading inference model.
                            See :ref:`api_guide_executor_en` for more details about it.
        model_filename(str, optional): One of the following:
          - The name of file to load the inference program.
          - If it is None, the default filename ``__model__`` will be used.
          - When ``dirname`` is ``None``, it must be set to a string containing model.
          Default: ``None``.
        params_filename(str, optional): It is only used for the case that all
            parameters were saved in a single binary file. One of the following:
          - The name of file to load all parameters.  
          - When ``dirname`` is ``None``, it must be set to a string containing all the parameters.
          - If parameters were saved in separate files, set it as ``None``.
            Default: ``None``.

        pserver_endpoints(list, optional): It is only needed by the distributed inference.
                                    If using a distributed look up table during the training,
                                    this table is also needed by the inference process. Its value is
                                    a list of pserver endpoints.

    Returns:
        list: The return of this API is a list with three elements:
        (program, feed_target_names, fetch_targets). The `program` is a
        ``Program`` (refer to :ref:`api_guide_Program_en`), which is used for inference.
        The `feed_target_names` is a list of ``str``, which contains names of variables
        that need to feed data in the inference program. The `fetch_targets` is a list of
        ``Variable`` (refer to :ref:`api_guide_Program_en`). It contains variables from which
        we can get inference results.


    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid
            import numpy as np

            paddle.enable_static()
            # Build the model
            main_prog = fluid.Program()
            startup_prog = fluid.Program()
            with fluid.program_guard(main_prog, startup_prog):
                data = fluid.layers.data(name="img", shape=[64, 784], append_batch_size=False)
                w = fluid.layers.create_parameter(shape=[784, 200], dtype='float32')
                b = fluid.layers.create_parameter(shape=[200], dtype='float32')
                hidden_w = fluid.layers.matmul(x=data, y=w)
                hidden_b = fluid.layers.elementwise_add(hidden_w, b)
            place = fluid.CPUPlace()
            exe = fluid.Executor(place)
            exe.run(startup_prog)

            # Save the inference model
            path = "./infer_model"
            fluid.io.save_inference_model(dirname=path, feeded_var_names=['img'],
                         target_vars=[hidden_b], executor=exe, main_program=main_prog)

            # Demo one. Not need to set the distributed look up table, because the
            # training doesn't use a distributed look up table.
            [inference_program, feed_target_names, fetch_targets] = (
                fluid.io.load_inference_model(dirname=path, executor=exe))
            tensor_img = np.array(np.random.random((1, 64, 784)), dtype=np.float32)
            results = exe.run(inference_program,
                          feed={feed_target_names[0]: tensor_img},
                          fetch_list=fetch_targets)

            # Demo two. If the training uses a distributed look up table, the pserver
            # endpoints list should be supported when loading the inference model.
            # The below is just an example.
            endpoints = ["127.0.0.1:2023","127.0.0.1:2024"]
            [dist_inference_program, dist_feed_target_names, dist_fetch_targets] = (
                fluid.io.load_inference_model(dirname=path,
                                              executor=exe,
                                              pserver_endpoints=endpoints))

            # In this example, the inference program was saved in the file
            # "./infer_model/__model__" and parameters were saved in
            # separate files under the directory "./infer_model".
            # By the inference program, feed_target_names and
            # fetch_targets, we can use an executor to run the inference
            # program for getting the inference result.
    FNz There is no directory named '%s'r   rbTzBThe path of params cannot be None when the directory path is None.z Unsupported program version: %d
c                    s   g | ]	}   |qS r=   )r   r`   r   rq   r=   r>   r   #  s    z(load_inference_model.<locals>.<listcomp>)r   rU   r   isdirrZ   r   r  rY   readr	   Zparse_from_stringr#   Z_is_program_version_supported_versionr,   _endpoints_replacementrb   Zget_feed_target_namesZget_fetch_target_names)r   r   r  r  Zpserver_endpointsZload_from_memoryZload_dirnamer  Zprogram_desc_strr   r   Zfetch_targetsr=   rq   r>   r.     sL   a







r.   c                 C   s6   d}|   jD ]}||r||| q|   | S )Nr   )r   r	  Zhas_attrZset_attrr   )rr   r   ZENDPOINT_MAPr  r=   r=   r>   r  *  s   
r  c                 C   s>   t | sJ dt }| }t|| }|j|i |gdd S )a  
    Get the LoDTensor value of the given parameter.

    Args:
        para(Parameter): The parameter to get value from.
        executor(Executor): The executor to run for retrieving the value.

    Returns:
        numpy.array: The given parameter's values.

    Raises:
        AssertionError: If the `para` is not an instance of Parameter.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            param = fluid.default_main_program().global_block().var('fc.w')
            p = fluid.io.get_parameter_value(param, exe)

    z$The input variable is not parameter.)r   Z
fetch_listr   )ra   r	   r   r}   r   )parar   Zget_programr|   r   r=   r=   r>   get_parameter_value3  s
   
r  c                 C   s&   |du rt  }| | }t||S )a	  
    Get the LoDTensor value of a certain parameter by its name.

    Args:
        name(str): The parameter's name.
        executor(Executor): The executor to run for retrieving the value.
        program(Program | None): The program where to find the parameter.
                               If it's set to be None, the function will
                               try to find the parameter in the default
                               main program.

    Returns:
        numpy.array: The parameter's values.

    Examples:
        .. code-block:: python

            import paddle
            import paddle.fluid as fluid

            paddle.enable_static()
            exe = fluid.Executor(fluid.CPUPlace())
            p = fluid.io.get_parameter_value('fc.w', exe)
    N)r   r   r`   r  )ru   r   rr   r`   r=   r=   r>   get_parameter_value_by_nameU  s   
r   c              	   C   s   t  }g }| }|D ]}t| }||vr"|| || qt }g }	|D ]7}| }
|
	 t
jjjksB|
	 t
jjjkrCq*| j|
 |
 |
 |
	 |
 |
 d}|	| q*t| ||	d dS )a  
    Save persistable nodes to the given directory by the executor.

    Args:
        executor(Executor): The executor to run for saving node values.
        dirname(str): The directory path.
        graph(IrGraph): All the required persistable nodes in the graph will be saved.
    rt   r   r   r   N)setall_persistable_nodescptto_textru   addr   r	   r`   rc   r#   rd   re   r   rh   r   rz   rv   rw   rx   ri   r'   )r   r   graphpersistable_node_namespersistable_nodesr#  noderu   rr   var_listvar_descr`   r=   r=   r>   _save_persistable_nodest  s4   	

r-  c              	      s   t  }g }| }|D ]}t| }||vr"|| || qt }g }	 fdd}
|D ]E}| }|	 t
jjjksH|	 t
jjjkrIq0| j| | | |	 | | d}|
|rl|	| q0td|   q0t|  |	d dS )a&  
    Load persistable node values from the given directory by the executor.

    Args:
        executor(Executor): The executor to run for loading node values.
        dirname(str): The directory path.
        graph(IrGraph): All the required persistable nodes in the graph will be loaded.
    c                    s   t jt j | jS r8   )r   rU   r   r   ru   r_   r   r=   r>   _exist  s   z'_load_persistable_nodes.<locals>._existrt   zCannot find the var %s!!!r!  N)r"  r#  r$  r%  ru   r&  r   r	   r`   rc   r#   rd   re   r   rh   r   rz   rv   rw   rx   ri   _loggerr   r*   )r   r   r'  r(  r)  r#  r*  ru   rr   r+  r/  r,  r`   r=   r.  r>   _load_persistable_nodes  s:   	

r1  c                 C   sB  i }i }d|  k rdk rzn njt | trz|  D ]`\}}t |tjrytd|jj }t|j	}||kryi ||< |j	|| d< g || d< |
 }ttt|d | D ]!}|d t| }	|| d |	 ||| ||d   ||	< qWq|r| D ]\}}|| v r| | |d D ]}
||
 | |
< qq|| d< | S )	Nr      i?OriginShaper   g      ?z@@.UnpackBigParamInfor@@)rS   dictr   r   ndarrayintrw   itemsizeprodrv   flattenrangemathceilrT   r   pop)Z	saved_objprotocolZtemp_saved_objZunpack_inforkeyvalueZMAX_NUMBER_OF_ELEMENTZnum_elementr   Z	part_namepartr=   r=   r>   _unpack_saved_dict  sV   




rC  c                    s   t  trDd}| v rDg } |  D ]!\}} fdd|d D }t||d  |< ||d 7 }q|D ]} | q7 |  S )Nr4  c                    s   g | ]} | qS r=   r=   )r   rB  load_objr=   r>   r     r   z%_pack_loaded_dict.<locals>.<listcomp>r   r3  )rS   r5  r   r   ZconcatenateZreshaper>  )rE  Zunpack_infoZremovesr@  rA  r   r=   rD  r>   _pack_loaded_dict  s   


rF  c                    s   dd   fddD t |rTtjdkrTtjjdkrTtj|d}t|d!}d	}td
t	||D ]}|
||||   q4W d    d S 1 sMw   Y  d S t|d}tj||d W d    d S 1 smw   Y  d S )Nc                 S   s6   t | tjtjjfr|  S t | tjrt| S | S r8   )	rS   r#   ZVarBaseeagerZTensornumpyZ	LoDTensorr   r   r_   r=   r=   r>   r     s
   
z _legacy_save.<locals>.get_tensorc                    s   i | ]	}| | qS r=   r=   r   r   
param_dictr=   r>   
<dictcomp>  s    z _legacy_save.<locals>.<dictcomp>darwin   r?  r     @r   )rV   sysplatformversion_infomajorpickledumpsrY   r;  r   r  r]   dump)rJ  
model_pathr?  pickle_bytesr  	max_bytesr   r=   rI  r>   _legacy_save  s    ""rZ  r2  c                    sb  t j|}|dksJ dd|v r|d }td t|ts)tdt	||dk s1|dkr8td|t j
|}|rKt j|sKt | d	d
  ttt|  } fdd|D }t||}tjdkrtjjdkrtj||d}t|d d }	d}
tdt||
D ]}|	||||
   qW d   n1 sw   Y  nt|d d}	tj||	|d W d   n1 sw   Y  ttt|  } fdd|D }t|d d}	tj||	|d W d   n1 sw   Y  |  }| j   |j!  t"j#j$%| j t|d d}	|	| j&  W d   dS 1 s*w   Y  dS )an  
    
    This function save parameters, optimizer information and network description to model_path.

    The parameters contains all the trainable Tensor, will save to a file with suffix ".pdparams".
    The optimizer information contains all the Tensor used by optimizer. For Adam optimizer, contains beta1, beta2, momentum etc. All the information will save to a file with suffix ".pdopt". (If the optimizer have no Tensor need to save (like SGD), the fill will not generated).
    The network description is the description of the program. It's only used for deployment. The description  will save to a file with a suffix ".pdmodel".

    Args:
        program(Program) : The program to saved.
        model_path(str): the file prefix to save the program. The format is "dirname/file_prefix". If file_prefix is empty str. A exception will be raised
        protocol(int, optional): The protocol version of pickle module must be greater than 1 and less than 5.
                                 Default: 4
        configs(dict, optional) : optional keyword arguments.                        

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.static as static

            paddle.enable_static()

            x = static.data(name="x", shape=[10, 10], dtype='float32')
            y = static.nn.fc(x, 10)
            z = static.nn.fc(y, 10)

            place = paddle.CPUPlace()
            exe = static.Executor(place)
            exe.run(static.default_startup_program())
            prog = static.default_main_program()

            static.save(prog, "./temp")
    r   zThe input model_path MUST be format of dirname/filename [dirname\filename in Windows system], but received model_path is empty string.Zpickle_protocolzJ'pickle_protocol' is a deprecated argument. Please use 'protocol' instead.z-The 'protocol' MUST be `int`, but received {}r$   r2  z1Expected 1<'protocol'<5, but received protocol={}c                 S   s   t  | j }t|S r8   )r   r   ru   r   r   r   )r`   tr=   r=   r>   r   O  s   
zsave.<locals>.get_tensorc                       i | ]}|j  |qS r=   r   r   pr   r=   r>   rK  T      zsave.<locals>.<dictcomp>rL  rM  rN  	.pdparamsr  rO  r   Nc                    r\  r=   r   r]  r_  r=   r>   rK  f  r`  .pdopt.pdmodel)'r   rU   r  r   r   rS   r7  rZ   r[   rc   r   r   r
  rn   ro   ra   rp   rC  rP  rQ  rR  rS  rT  rU  rY   r;  r   r  rV  rl   r  rb   rQ   r  r~   r   r#   r  r  )rr   rW  r?  Zconfigs	base_namedir_nameparameter_listrJ  rX  r  rY  r   optimizer_var_listZopt_dictr   r=   r_  r>   r0     sh   (





$r0   c                 C   sJ   t d}tj| }d}td||D ]	}|||7 }qtj|dd}|S )Nr   rO  latin1encoding)	bytearrayr   rU   getsizer;  r  rT  loads)rU   r  rX  	file_sizerY  _Zload_resultr=   r=   r>   _pickle_loads_macs  s   rp  c              
   C   sL  |du st |tsJ |}|dr|dd }n|dr%|dd }n|dr0|dd }|d }tj|sLtd| |du rKt	d	|durWd
d |D }nd}tj
|rt }tj|ddD ]\}}	}
|
D ]}|tj||dd qpqit|  }g }|D ]'}tj||jdd}|du p|j|v }||v r|r|| || qt|dkrdt|}tddt|  z
t|||d W dS  ty } zt| |d}~w   tdtj|rL|dkrt	d|  }tdd |D }|D ]}|j|vrtdqtj|\}}zt||||d W dS  tyE } zt| |d}~w   tddd }ttt|  }|rgtj j!"|t# |j$ t%|d&}t&j'dkrt&j(j)dkrt*||}nt+j,|dd }t-|}W d   n	1 sw   Y  |D ]}|j|v sJ d!|j|||||j  qttt.|  }t|dkr"|d }tj|sJ d"||rtj j!"|t# |j$ t%|d}t+j,|dd }W d   n	1 s w   Y  |D ]}|j|v sJ d!|j|||||j  qdS dS )#a%  
    :api_attr: Static Graph

    This function get parameters and optimizer information from program, and then get corresponding value from file.
    An exception will throw if shape or dtype of the parameters is not match.

    This function can also load model file saved with [ save_params, save_persistables, save_vars ].
    var_list can not be None  when load single model file
    ( filename is not None When save_params, save_persistables or save_vars is called ).

    Args:
        program(Program): The program will be loaded
        model_path(str): The file prefix store the program
        executor(Executor, optional): The executor used for initialize the parameter
                                      When startup program is not run.
        var_list(list|tuple, optional): The Tensor list/tuple to load single model file saved with
                                  [ save_params, save_persistables, save_vars ].
                                  Default: None

    Returns:
        None

     Examples:
        .. code-block:: python

            import paddle
            import paddle.static as static

            paddle.enable_static()

            x = static.data(name="x", shape=[10, 10], dtype='float32')
            y = static.nn.fc(x, 10)
            z = static.nn.fc(y, 10)

            place = paddle.CPUPlace()
            exe = static.Executor(place)
            exe.run(static.default_startup_program())
            prog = static.default_main_program()

            static.save(prog, "./temp")
            static.load(prog, "./temp")
    Nra  rb  rc  ]{} not found, try to load model file saved with [ save_params, save_persistables, save_vars ]zeexecutor is required when loading model file saved with [ save_params, save_persistables, save_vars ]c                 S   r   r=   r   r   r=   r=   r>   r     r   zload.<locals>.<listcomp>Ftopdown\/r    zvariable file [ %s ] not usedr!  zFailed to load model file, please make sure model file is saved with the following APIs: save_params, save_persistables, save_varszevar_list is required when loading model file saved with [ save_params, save_persistables, save_vars ]c                 S   r   r=   r   r   r=   r=   r>   r     r   z/loaded var [{}] is not in program variable listr   r   r   r   zFailed to load model file , please make sure model file is saved with the the following APIs: [ save_params, save_persistables, save_vars ]. When these API called, filename CANNOT be Nonec                 S   s  t  | j }| }| rtj }nm|	 r!tj
 }nc| r;tjj }||  tj| }nI| rUtjj }||  tj| }n/| rotjj }||  tj| }ntjj }||  tj| }||| d S r8   )r   r   ru   r   _placeZis_cpu_placer~   r   CPUPlaceis_cuda_pinned_placeCUDAPinnedPlaceis_xpu_placer#   Place	set_placeXPUPlacexpu_device_idis_npu_placeNPUPlacenpu_device_idis_mlu_placeMLUPlacemlu_device_id	CUDAPlacegpu_device_idr"  )r`   r6  r[  r^  placer=   r=   r>   set_var  s,   zload.<locals>.set_varr  rL  rM  rh  ri  z$Can not find [{}] in model file [{}]zOptimizer file [{}] not exits)/rS   r   endswithr   rU   r   r0  debugr[   rZ   r  r"  walkr&  r   replacern   rp   ru   r   remover   warningr*   r   errorr   LookupErrorsplitro   ra   r~   r   r#   Z_create_loaded_parameterr   _default_executorrY   rP  rQ  rR  rS  rp  rT  r1   rF  rl   )rr   rW  r   r+  model_prefixparameter_file_nameZvar_list_namesZbinary_file_setrootdirsfilesr  Zprogram_var_listloaded_var_listr`   r   Zload_conditionZunused_var_listr  Zprogram_var_name_setre  	file_namer  rf  	load_dictr  rg  opt_file_namer=   r=   r>   r1   }  s   -










r1   c                 C   s  | }| dr|dd }n| dr|dd }n| dr%|dd }|d }tj|std| g }|du rHtj| rHtd	tj	| d
dD ]#\}}}|D ]}tj
||}	tj|	| }
|
dd}
||
 qVqOt  t }| }dd }	ddd}tj }tj|}g }tj| rtj| \}}|D ]
}|||| q||||| n3|dur|D ]
}|||| q||| |d n|D ]}|j|dd}||| |gdd
r|| qi }|D ]}ttj |j ||j< q|W  d   S 1 sw   Y  tj|s#J d|t|d"}tjdkr<tj j!dkr<t"||}nt#j$|dd}W d   n	1 sNw   Y  t%|}|d }tj|rt|d}t#j$|dd}W d   n	1 szw   Y  |&| |S )an  

    Load program state from local file

    Args:
        model_path(str): The file prefix store the program
        var_list(list|tuple, optional): The Tensor list/tuple to load saved with
                                  [ save_params, save_persistables, save_vars ].
                                  Default: None.
                                  The var_list is only used to get name,
                                  will not be modified.
    Returns:
        state_dict(dict): the dict store Parameter and optimizer information

    Examples:
    
        .. code-block:: python

            import paddle
            import paddle.static as static

            paddle.enable_static()

            x = static.data(name="x", shape=[10, 10], dtype='float32')
            y = static.nn.fc(x, 10)
            z = static.nn.fc(y, 10)

            place = paddle.CPUPlace()
            exe = static.Executor(place)
            exe.run(static.default_startup_program())
            prog = static.default_main_program()

            static.save(prog, "./temp")
            program_state = static.load_program_state("./temp")
    ra  Nrq  rb  rr  rc  rs  rt  z7var_list can not be None when model_path is a file typeFru  rw  rx  c                 S   sP   t |ts	td| j|j|j|j|j|j t	j
jjkr#|jddS d ddS )Nz"value in var_list must be variableTrt   )rS   r   r   rz   ru   rv   rw   rc   rb   r#   rd   re   ry   rx   r{   r=   r=   r>   clone_var_to_block  s   
z.load_program_state.<locals>.clone_var_to_blockTc                 S   sb   zt | |||d W dS    d}|d u rdd |D n|}|r&t|| t|| t Y dS )Nrz  TzFailed to load model/variables `%s`, please make sure model/variables file is saved with the following APIs: save_params, save_persistables, save_vars.c                 S   r   r=   r   r   r=   r=   r>   r     r   zIload_program_state.<locals>._load_vars_with_try_catch.<locals>.<listcomp>F)r*   r   r   r   RuntimeWarning)exer   r   r   Zraise_errorZ	error_str	filenamesr=   r=   r>   _load_vars_with_try_catch  s"   z5load_program_state.<locals>._load_vars_with_try_catch)ru   ri   zParameter file [{}] not exitsr  rL  rM  rh  ri  )T)'r  r   rU   r   r0  r  r[   r   rZ   r  r   relpathr  r   r   r	   r   r~   r   r|  r   r  rz   r   Zasarrayr   r   ru   r   rY   rP  rQ  rR  rS  rp  rT  r1   rF  update)rW  r+  r  r  Zvar_name_listr  r  r  r  r   Zvar_temp_namer   r   r  r  r  r  r  re  r  r`   var_nameZtemp_varZres_dictZ	para_dictr  Z	opti_dictr=   r=   r>   r2   F  s   $





"O
r2   c                 C   s  t |}ttt|  }i }|D ]}tj |j	}|dks(J d
|j	|j	|v rt| }||j	 }|j|jksKJ d
|j|j	|j|j|jks]J d
|j|j	|j| }| }	tj }
|	 rttj }n_|	 rtjj }||	 tj| }
nG|	 rtjj }||	 tj| }
n/|	 rtjj }||	 tj| }
n|	  rtjj }||	 tj!|" }
|#||
 d||j	< qg }|$ D ]\}}||vr|%| qt&|dkrt'(d
d)| dS dS )	a  
    Set program parameter from state_dict

    An exception will throw if shape or dtype of the parameters is not match.

    NOTICE: This function MUST called after run start_up_program

    Args:
        program(Program): The program to be set
        state_dict(dict): the dict store Parameter and optimizer information
    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            import paddle.static as static

            paddle.enable_static()

            x = static.data(name="x", shape=[10, 10], dtype='float32')
            y = static.nn.fc(x, 10)
            z = static.nn.fc(y, 10)

            place = paddle.CPUPlace()
            exe = static.Executor(place)
            exe.run(static.default_startup_program())
            prog = static.default_main_program()

            static.save(prog, "./temp")
            program_state = static.load_program_state("./temp")

            static.set_program_state(prog, program_state)
    Nz?Variable [ {} ] Not found, Please make sure run startup programzParameter's shape does not match, the Program requires a parameter with the shape of ({}), while the loaded parameter (namely [ {} ]) has a shape of  ({}).zParameter's data type does not match, the Program requires a parameter with a dtype of ({}), while the loaded parameter (namely [ {} ]) has a dtype of  ({}).r   r   zOThis list is not set, Because of Paramerter not found in program. There are: {}ry  )*rF  rn   ro   rj   rp   r~   r   r   r   ru   r[   r   r   r   rv   rw   r{  r|  r}  r~  Zis_gpu_placer#   r  r  r  r  r  r  r  r  r  r  r  r  r  r"  r   r   r   r   r   r   )rr   Z
state_dictrf  Zused_para_listr  r   Zorig_para_npZnew_para_nptenZ	ten_placeZpy_placer  r^  Zunused_para_listkr  r=   r=   r>   r3     sl   %










r3   )NNNr8   )NNNN)NN)r   )r   )NNNTFT)r$   )r2  )i
__future__r   r   r  r   r   loggingrT  
contextlib	functoolsr   rP  ior   rH  r   r<  r~   Zpaddle.fluidr   Zpaddle.fluid.executorr   r   Zpaddle.fluid.evaluatorr   Zpaddle.fluid.frameworkr	   r
   r   r   r   r   r   r   Zpaddle.readerr   r   r   r   r   r   r   r   r   r   wrapped_decoratorr   Zpaddle.fluid.compilerr   Zpaddle.fluid.log_helperr   r   r   r    r"   r#   r%   r$  Zpaddle.utilsr&   r/   __all__rB   INFOr0  objectr7   rE   rP   rV   r]   r^   ra   rj   rl   r4   r5   r}   r   r   r'   r(   r   r)   r*   r+   r,   r   r   r   r-   r.   r  r  r   r-  r1  rC  rF  rZ  r0   rp  r1   r2   r3   r=   r=   r=   r>   <module>   s   (0	


 I H
 i<
7h


 R
 	
"#*%a
 
I %