o
    Qe                     @   sl  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
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 d dlmZmZ d dlmZmZ d dlmZ g Zee ej!dd	Z"d,d
dZ#dd Z$dd Z%d-ddZ&dd Z'dd Z(dd Z)edd Z*dd Z+edd Z,dd Z-d d! Z.ed"d# Z/ed$d% Z0ed&d' Z1d(d) Z2ed*d+ Z3dS ).    )print_functionN)coreVariableCompiledProgramdefault_main_programProgramlayersunique_nameprogram_guard)prepend_feed_opsappend_fetch_ops)static_only	Parameter)Executorglobal_scope)
get_loggerz&%(asctime)s-%(levelname)s: %(message)s)fmtc                 C   sb   |d u rg n|}|d u rg n|}|D ]}||v r!t d|| |||vr.t d| ||qd S )NzDargument '{}' in function '{}' is deprecated, only {} are supported.zDfunction '{}' doesn't support argument '{}',
 only {} are supported.)
ValueErrorformat)callerargssupported_argsdeprecated_argsarg r   @D:\Projects\ConvertPro\env\Lib\site-packages\paddle/static/io.py_check_args0   s"   r   c                 C   s8   t |ts|g}|rtdd |D std| d S )Nc                 S   s   g | ]}t |tqS r   
isinstancer   .0varr   r   r   
<listcomp>E   s    z_check_vars.<locals>.<listcomp>z0'{}' should be a Variable or a list of Variable.)r   listallr   r   )nameZvar_listr   r   r   _check_varsB   s   
r&   c                 C   sB   t | tjs
td| drtdtj| } tj| } | S )z/
    convert path_prefix to absolute path.
    z!'path_prefix' should be a string./z''path_prefix' should not be a directory)	r   sixstring_typesr   endswithospathnormpathabspath)path_prefixr   r   r   _normalize_path_prefixK   s   
r0   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 )z9
    return default main program if program is None.
    NzQThe type of input program is invalid, expected tyep is Program, but received Nonez8The input is a CompiledProgram, this is not recommended.zUThe type of input program is invalid, expected type is fluid.Program, but received %s)	r   r   r   Z_program	TypeErrorwarningswarnr   typeprogramr   r   r   _get_valid_programX   s$   

r7   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)r%   shapedtyper4   	lod_levelpersistable)r%   r8   r9   r4   r;   )r   r   descr4   r   VarDescVarTypeZ
LOD_TENSOR
create_varr%   r8   r9   r:   )blockr!   r   r   r   _clone_var_in_blocko   s"   	rA   c                 C   s  t | tstdt|  t |ts|g}tdd |D s"tdt |ts*|g}tdd |D s7td|  jD ]}tj	
 }||d |jdkrUtd	  nq<t| + g }t|D ]\}}|jtjkrvtj|d
d|d}|| qa|}W d   n1 sw   Y  |  }| }	g }
t|	jD ]\}}|jd |jdks|jdkr|
| q|
ddd D ]}|	| q|j  dd |D }|j||d}|jdd}dd |D }t|| t|| |j   |S )a  
    :api_attr: Static Graph

    Normalize/Optimize a program according to feed_vars and fetch_vars.

    Args:
        program(Program): Specify a program you want to optimize.
        feed_vars(Variable | list[Variable]): Variables needed by inference.
        fetch_vars(Variable | list[Variable]): Variables returned by inference.

    Returns:
        Program: Normalized/Optimized program.

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # normalize main program.
            program = paddle.static.default_main_program()
            normalized_program = paddle.static.normalize_program(program, [image], [predict])

    7program type must be `fluid.Program`, but received `%s`c                 s       | ]}t |tV  qd S Nr   r    vr   r   r   	<genexpr>       z$normalize_program.<locals>.<genexpr>z8feed_vars type must be a Variable or a list of Variable.c                 s   rC   rD   r   rE   r   r   r   rG      rH   z9fetch_vars type must be a Variable or a list of Variable. ZauczHBe sure that you have set auc states to 0 before saving inference model.g      ?zsave_infer_model/scale_{}r%   NFfeedfetchc                 S      g | ]}|j qS r   rJ   r   r   r   r   r"          z%normalize_program.<locals>.<listcomp>)Zfeeded_var_namestargetsT)Zprune_read_opc                 S   rN   r   rJ   r   r   r   r   r"      rO   )!r   r   r1   r4   r#   r$   global_blockopsr   Zop_proto_and_checker_makerZkOpDeviceAttrNameZ	_set_attrr2   r3   r
   	enumerater9   paddleboolr   scaler   appendcloner<   Zset_is_targetZ
_remove_opflushZ_prune_with_inputZ_inference_optimizer   r   Z_set_version)r6   	feed_vars
fetch_varsopZdevice_attr_nameZuniq_fetch_varsir!   Zcopy_programrQ   Zremove_op_idxidxZfeed_var_namesZfetch_var_namesr   r   r   normalize_program   st   
&










r_   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)	r<   r4   r   r=   r>   ZFEED_MINIBATCHZ
FETCH_LISTZREADERr;   )r!   r   r   r   is_persistable   s
   r`   c                 K   s8   t d|  t d| t|dd}t|| |}t|S )a  
    :api_attr: Static Graph

    Serialize default main program according to feed_vars and fetch_vars.

    Args:
        feed_vars(Variable | list[Variable]): Variables needed by inference.
        fetch_vars(Variable | list[Variable]): Variables returned by inference.
        kwargs: Supported keys including 'program'.Attention please, kwargs is used for backward compatibility mainly.
          - program(Program): specify a program if you don't want to use default main program.

    Returns:
        bytes: serialized program.

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # serialize the default main program to bytes.
            serialized_program = paddle.static.serialize_program([image], [predict])

            # deserialize bytes to program
            deserialized_program = paddle.static.deserialize_program(serialized_program)

    rZ   r[   r6   N)r&   r7   getr_   _serialize_program)rZ   r[   kwargsr6   r   r   r   serialize_program  s
   
+
rd   c                 C   s
   | j  S )z+
    serialize given program to bytes.
    )r<   Zserialize_to_stringr5   r   r   r   rb   ?  s   
rb   c                 K   s:   t d|  t d| t|dd}t|| |}t||S )aD  
    :api_attr: Static Graph

    Serialize parameters using given executor and default main program according to feed_vars and fetch_vars.

    Args:
        feed_vars(Variable | list[Variable]): Variables needed by inference.
        fetch_vars(Variable | list[Variable]): Variables returned by inference.
        kwargs: Supported keys including 'program'.Attention please, kwargs is used for backward compatibility mainly.
          - program(Program): specify a program if you don't want to use default main program.

    Returns:
        bytes: serialized program.

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # serialize parameters to bytes.
            serialized_params = paddle.static.serialize_persistables([image], [predict], exe)

            # deserialize bytes to parameters.
            main_program = paddle.static.default_main_program()
            deserialized_params = paddle.static.deserialize_persistables(main_program, serialized_params, exe)

    rZ   r[   r6   N)r&   r7   ra   r_   _serialize_persistables)rZ   r[   executorrc   r6   r   r   r   serialize_persistablesF  s
   
,

rg   c                 C   s   t tt|  }t|dkrtd dS t }| }i }|D ]}|j	t
jjjkr5t||}|||j< q!g }t| D ]	}	|||	  q>td}
|jt
jjj|
d}|jd |jdd|id	|id
ddd |  || t |
 S )z@
    Serialize parameters using given program and executor.
    r   zVno variable in your model, please ensure there are any variables in your model to saveNout_var)r4   r%   TZsave_combineXYrI   )	file_pathZsave_to_memoryr4   ZinputsZoutputsattrs)r#   filterr`   	list_varslenr2   r3   r   rQ   r4   r   r=   r>   RAWrA   r%   sortedkeysrW   r	   generater?   r<   Zset_persistable	append_opZ_sync_with_cpprunr   find_var	get_bytes)r6   rf   vars_Zsave_programZ
save_blockZsave_var_mapr!   var_copyZin_varsr%   Zout_var_namerh   r   r   r   re   {  s>   





re   c                 C   sL   t |ts	tdt| d}|| W d   dS 1 sw   Y  dS )ue  
    Save content to given path.
    Args:
        path(str): Path to write content to.
        content(bytes): Content to write.
    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle
            paddle.enable_static()
            path_prefix = "./infer_model"
            # 用户自定义网络，此处用 softmax 回归为例。
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')
            loss = paddle.nn.functional.cross_entropy(predict, label)
            exe = paddle.static.Executor(paddle.CPUPlace())
            exe.run(paddle.static.default_startup_program())
            # 序列化参数
            serialized_params = paddle.static.serialize_persistables([image], [predict], exe)
            # 将序列化之后的参数保存到文件
            params_path = path_prefix + ".params"
            paddle.static.save_to_file(params_path, serialized_params)
    z'content' type should be bytes.wbN)r   bytesr   openwrite)r,   contentfr   r   r   save_to_file  s
   
"r   c              
   K   s  t | } ztj| }t| W n ty* } z|jtjkr  W Y d}~nd}~ww | d }| d }tj|r@t	d
|tj|rMt	d
|td| td| t|dd}	|dd	}
t|	||}	t|	j|
d
}t|| t|	|}|durt|| dS dS )ad	  
    Save current model and its parameters to given path. i.e.
    Given path_prefix = "/path/to/modelname", after invoking
    save_inference_model(path_prefix, feed_vars, fetch_vars, executor),
    you will find two files named modelname.pdmodel and modelname.pdiparams
    under "/path/to", which represent your model and parameters respectively.

    Args:
        path_prefix(str): Directory path to save model + model name without suffix.
        feed_vars(Variable | list[Variable]): Variables needed by inference.
        fetch_vars(Variable | list[Variable]): Variables returned by inference.
        executor(Executor): The executor that saves the inference model. You can refer
                            to :ref:`api_guide_executor_en` for more details.
        kwargs: Supported keys including 'program' and "clip_extra". Attention please, kwargs is used for backward compatibility mainly.

            - program(Program): specify a program if you don't want to use default main program.

            - clip_extra(bool): the flag indicating whether to clip extra information for every operator. Default: True.

    Returns:
        None

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # Feed data and train process

            # Save inference model. Note we don't save label and loss in this example
            paddle.static.save_inference_model(path_prefix, [image], [predict], 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 file "./infer_model.pdmodel"
            # and parameters are going to be saved in file "./infer_model.pdiparams".

    N.pdmodel
.pdiparamsz'{}' is an existing directory.rZ   r[   r6   
clip_extraT)r   )r0   r+   r,   dirnamemakedirsOSErrorerrnoEEXISTisdirr   r   r&   r7   ra   r_   rb   Z_remove_training_infor   re   )r/   rZ   r[   rf   rc   r   e
model_pathparams_pathr6   r   program_bytesparams_bytesr   r   r   save_inference_model  s:   :




r   c                 C   s,   t | }t| std|  |S )ad  
    :api_attr: Static Graph

    Deserialize given data to a program.

    Args:
        data(bytes): serialized program.

    Returns:
        Program: deserialized program.

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # serialize the default main program to bytes.
            serialized_program = paddle.static.serialize_program([image], [predict])

            # deserialize bytes to program
            deserialized_program = paddle.static.deserialize_program(serialized_program)

    z Unsupported program version: %d
)r   Zparse_from_stringr   Z_is_program_version_supported_versionr   )datar6   r   r   r   deserialize_program*  s   
'
r   c                 C   s  t | tstdt|  t }| }ttt|  }i }i }g }g }	|D ]>}
t |
t	s0J |
jt
jjjkr9q't |
trHt|
j ||
j< |
jt
jjjkrV|	|
 q't||
}||
 |||j< q'|du rvt|dkstJ ddS g }t| D ]	}|||  q~|jdi d|i|ddd	 || |D ]D}
t |
tsqtj |
j}|dksJ d
|
j t |! j"}|
j|v sJ |
jd |#|
j}||krt$d%||
j|qdS )ar  
    :api_attr: Static Graph

    Deserialize given data to parameters according to given program and executor.

    Args:
        program(Program): program that contains parameter names (to deserialize).
        data(bytes): serialized parameters.
        executor(Executor): executor used to run load op.

    Returns:
        Program: deserialized program.

    Examples:
        .. code-block:: python

            import paddle

            paddle.enable_static()

            path_prefix = "./infer_model"

            # User defined network, here a softmax regession example
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')

            loss = paddle.nn.functional.cross_entropy(predict, label)

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

            # serialize parameters to bytes.
            serialized_params = paddle.static.serialize_persistables([image], [predict], exe)

            # deserialize bytes to parameters.
            main_program = paddle.static.default_main_program()
            deserialized_params = paddle.static.deserialize_persistables(main_program, serialized_params, exe)


    rB   Nr   z]Required 'data' shall be not None if program contains parameter, but received 'data' is None.Zload_combineZOutT)rk   Zmodel_from_memoryrl   zcan't not find var: z MUST in var list.zoShape mismatch, program needs a parameter with shape ({}), but the loaded parameter ('{}') has a shape of ({}).)&r   r   r1   r4   rQ   r#   rn   r`   ro   r   r   r=   r>   rq   r   tupler<   	get_shaper%   ZSELECTED_ROWSrW   rA   rp   rr   rs   ru   rv   rT   Zfluidr   rw   nparrayZ
get_tensorr8   ra   RuntimeErrorr   )r6   r   rf   Zload_programZ
load_blockry   Zorigin_shape_mapZload_var_mapZ
check_varsZsparse_varsr!   rz   Zload_var_listr%   Zvar_tmpZ	new_shapeZorigin_shaper   r   r   deserialize_persistablesY  sr   
+





r   c                 C   s8   t | d}| }W d   |S 1 sw   Y  |S )u  
    Load file in binary mode.
    Args:
        path(str): Path of an existed file.
    Returns:
        bytes: Content of file.

    Examples:

        .. code-block:: python

            import paddle
            paddle.enable_static()
            path_prefix = "./infer_model"
            # 用户自定义网络，此处用 softmax 回归为例。
            image = paddle.static.data(name='img', shape=[None, 28, 28], dtype='float32')
            label = paddle.static.data(name='label', shape=[None, 1], dtype='int64')
            predict = paddle.static.nn.fc(image, 10, activation='softmax')
            loss = paddle.nn.functional.cross_entropy(predict, label)
            exe = paddle.static.Executor(paddle.CPUPlace())
            exe.run(paddle.static.default_startup_program())
            # 序列化参数
            serialized_params = paddle.static.serialize_persistables([image], [predict], exe)
            # 将序列化之后的参数保存到文件
            params_path = path_prefix + ".params"
            paddle.static.save_to_file(params_path, serialized_params)
            # 从文件加载序列化之后的参数
            serialized_params_copy = paddle.static.load_from_file(params_path)
    rbN)r}   read)r,   r   r   r   r   r   load_from_file  s   

r   c                    s  d}d}t  jj}t|||| | du r5td |dd}|dd}|du r.tdd}|}	|}
nt	| } |sD| d	 }| d
 }nY|dd}|dd}|du r\t
j| d}nt
j| |d	 }t
j|srt
j| |}|du r~t
j| d}nt
j| |d
 }t
j|st
j| |}td|| t|}	t
j|}t
j|}t
j||}d}
t
j|rt|}
t|	 t |
|  j } j } fdd|D } ||gS )aH  
    :api_attr: Static Graph

    Load inference model from a given path. By this API, you can get the model
    structure(Inference Program) and model parameters.

    Args:
        path_prefix(str | None): One of the following:
          - Directory path to save model + model name without suffix.
          - 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.
        kwargs: Supported keys including 'model_filename', 'params_filename'.Attention please, kwargs is used for backward compatibility mainly.
          - model_filename(str): specify model_filename if you don't want to use default name.
          - params_filename(str): specify params_filename if you don't want to use default name.

    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 numpy as np

            paddle.enable_static()

            # Build the model
            startup_prog = paddle.static.default_startup_program()
            main_prog = paddle.static.default_main_program()
            with paddle.static.program_guard(main_prog, startup_prog):
                image = paddle.static.data(name="img", shape=[64, 784])
                w = paddle.create_parameter(shape=[784, 200], dtype='float32')
                b = paddle.create_parameter(shape=[200], dtype='float32')
                hidden_w = paddle.matmul(x=image, y=w)
                hidden_b = paddle.add(hidden_w, b)
            exe = paddle.static.Executor(paddle.CPUPlace())
            exe.run(startup_prog)

            # Save the inference model
            path_prefix = "./infer_model"
            paddle.static.save_inference_model(path_prefix, [image], [hidden_b], exe)

            [inference_program, feed_target_names, fetch_targets] = (
                paddle.static.load_inference_model(path_prefix, exe))
            tensor_img = np.array(np.random.random((64, 784)), dtype=np.float32)
            results = exe.run(inference_program,
                          feed={feed_target_names[0]: tensor_img},
                          fetch_list=fetch_targets)

            # In this example, the inference program was saved in file
            # "./infer_model.pdmodel" and parameters were saved in file
            # " ./infer_model.pdiparams".
            # By the inference program, feed_target_names and
            # fetch_targets, we can use an executor to run the inference
            # program to get the inference result.
    )model_filenameparams_filename)Zpserver_endpointsNz/Load inference model from memory is deprecated.r   r   z8params_filename cannot be None when path_prefix is None.rI   r   r   Z	__model__zRThe old way to load inference model is deprecated. model path: {}, params path: {}c                    s   g | ]	}   |qS r   )rQ   r!   )r    r%   r5   r   r   r"   p  s    z(load_inference_model.<locals>.<listcomp>)inspectcurrentframef_codeco_namer   _loggerwarningra   r   r0   r+   r,   joinexistsr   r   r   basenamer   r   r<   Zget_feed_target_namesZget_fetch_target_names)r/   rf   rc   r   r   r   r   r   Zload_dirnamer   r   r   r   Zfeed_target_namesZfetch_target_namesZfetch_targetsr   r5   r   load_inference_model  sp   B





r   )NNrD   )4
__future__r   r   r   loggingr+   r2   r(   numpyr   rT   Zpaddle.fluidr   r   r   r   r   r   r	   r
   Zpaddle.fluid.ior   r   Zpaddle.fluid.frameworkr   r   Zpaddle.fluid.executorr   r   Zpaddle.fluid.log_helperr   __all____name__INFOr   r   r&   r0   r7   rA   r_   r`   rd   rb   rg   re   r   r   r   r   r   r   r   r   r   r   <module>   sR   (

	
i
3
4/#
\
.
i#