o
    0hb-                     @  s   d dl mZ d dlZd dlZd dlZd dlmZmZ d dlZd dl	m
Z er0d dlZd dlmZ eeZ	d d!ddZdd Z	d"d#ddZdS )$    )annotationsN)IOTYPE_CHECKING)_type_utils)FileLiketensortorch.Tensornamestrlocationbasepathdtype_overrideonnx.TypeProto | Nonereturnonnx.TensorProtoc                 C  sN  ddl }|durtj|jjntj| j}|dur)| | jkr)| | } |	 }||_
| |_|j| j |j	j|_|d|   d}| D ]\}	}
|j }|	|_t|
|_qOtj||}tj|rst| tj|}tj|st | t!|d}|"| j#dd$  W d   |S 1 sw   Y  |S )a  Create a TensorProto with external data from a PyTorch tensor.
    The external data is saved to os.path.join(basepath, location).

    Args:
        tensor: Tensor to be saved.
        name: Name of the tensor (i.e., initializer name in ONNX graph).
        location: Relative location of the external data file
            (e.g., "/tmp/initializers/weight_0" when model is "/tmp/model_name.onnx").
        basepath: Base path of the external data file (e.g., "/tmp/external_data" while model must be in "/tmp").


    Reference for ONNX's external data format:
        How to load?
        https://github.com/onnx/onnx/blob/5dac81ac0707bdf88f56c35c0a5e8855d3534673/onnx/external_data_helper.py#L187
        How to save?
        https://github.com/onnx/onnx/blob/5dac81ac0707bdf88f56c35c0a5e8855d3534673/onnx/external_data_helper.py#L43
        How to set ONNX fields?
        https://github.com/onnx/onnx/blob/5dac81ac0707bdf88f56c35c0a5e8855d3534673/onnx/external_data_helper.py#L88
    r   N)r   offsetlengthxbT)force)%onnxjit_type_utilsJitScalarTypefrom_onnx_typetensor_type	elem_type
from_dtypedtypetoTensorProtor	   	onnx_type	data_typedimsextendshapeEXTERNALdata_locationuntyped_storagenbytesitemsexternal_dataaddkeyr
   valueospathjoinexistsremovedirnamemakedirsopenwritenumpytobytes)r   r	   r   r   r   r   scalar_typetensor_protokey_value_pairskventryexternal_data_file_pathexternal_data_dir_path	data_file rA   Y/var/www/vscode/kcb/lib/python3.10/site-packages/torch/onnx/_internal/fx/serialization.py'_create_tensor_proto_with_external_data   sD   






rC   c                 C  sd   ddl m} i }|| ddd}| D ]}|| ||< qW d    |S 1 s+w   Y  |S )Nr   )	safe_openptcpu)	frameworkdevice)safetensorsrD   keys
get_tensorrF   )safetensors_filerD   tensorsfr;   rA   rA   rB   $_convert_safetensors_to_torch_formati   s   
rO   Fmodel_locationinitializer_locationtorch_state_dictstuple[dict | FileLike, ...]
onnx_modelonnx.ModelProtorename_initializerboolNonec                 C  s   ddl }i }dd t|jjD }dd |jjD }	|D ]}
t|
tr&|
}nft|
ttj	fr;t
|
dr;t|
}nQz
tj|
dd	d
}W nF ttfy } z8dt|v set|
tjtfr|
 r|
 rtd t|
tjtfrw|
d tj|
dd}n|W Y d}~nd}~ww | D ][\}}|r|dd}||	v r|	| n|	D ]}||s||r|}|	|  nqtj||}dd |jjD }||v r|||| < t|||| ||d}|jj | qqtt!| d	d}|" D ]}|jj|= q|#|tj| | dS )a  Load PyTorch tensors from files and add to "onnx_model" as external initializers.

    Output files:
        ONNX model file path:
        ONNX initializer folder: os.path.join(basepath, initializer_location)

    After running this function, you can do
        ort_sess = onnxruntime.InferenceSession(os.path.join(basepath, model_location))
    to execute the model.

    Arguments:
        basepath: Base path of the ONNX external data file (e.g., "/path/to/large_model/").
        model_location: Relative location of the ONNX model file.
            E.g., "model.onnx" so that the model file is saved to
            "<basepath>/model.onnx".
        initializer_location: Relative location of the ONNX initializer folder.
            E.g., "initializers" so that the initializers are saved to
            "<basepath>/initializers/".
            Note: When initializers are >2GB, must be the same as `model_location`.
        torch_state_dicts: Dictionaries or files which contain PyTorch tensors to be saved
            as ONNX initializers. For non-dict arguments, `torch.load` will be used to load them from file-like objects.
        onnx_model: ONNX model to be saved with external initializers.
            If an input name matches a tensor loaded from "torch_state_dicts",
            the tensor will be saved as that input's external initializer.
        rename_initializer: Replaces "." by "_" for all ONNX initializer names.
            Not needed by the official torch.onnx.dynamo_export. This is a hack
            for supporting `FXSymbolicTracer` tracer with fake tensor mode.
            In short, `FXSymbolicTracer` lifts FX parameters (self.linear_weight)
            as inputs (`def forward(self, linear_weight)`) and therefore, `.` cannot be used.
    r   Nc                 S  s   i | ]\}}|j |qS rA   r	   ).0idxr;   rA   rA   rB   
<dictcomp>   s    z1save_model_with_external_data.<locals>.<dictcomp>c                 S  s   h | ]}|j qS rA   rY   )rZ   inputrA   rA   rB   	<setcomp>   s    z0save_model_with_external_data.<locals>.<setcomp>z.safetensorsrF   T)map_locationmmapz+mmap can only be used with files saved withzFailed to load the checkpoint with memory-map enabled, retrying without memory-map.Consider updating the checkpoint with mmap by using torch.save() on PyTorch version >= 1.6.)r_   ._c                 S  s   i | ]}|j |jqS rA   )r	   type)rZ   r;   rA   rA   rB   r\      s    )reverse)$r   	enumerategraphinitializerr]   
isinstancedictr
   r-   PathLikefspathendswithrO   torchloadRuntimeError
ValueErrorioIOBaser   readableseekablelogwarningseekr(   replacer1   r.   r/   rC   popappendsortedrJ   save)r   rP   rQ   rR   rT   rV   r   initializers_to_be_deletedexisting_initializersonnx_input_namesel
state_dicter	   r   onnx_input_namerelative_tensor_file_pathmodel_input_typesr9   r[   rA   rA   rB   save_model_with_external_datav   s~   '





0r   )N)r   r   r	   r
   r   r
   r   r
   r   r   r   r   )F)r   r
   rP   r
   rQ   r
   rR   rS   rT   rU   rV   rW   r   rX   )
__future__r   rq   loggingr-   typingr   r   rm   
torch.onnxr   r   r   torch.typesr   	getLogger__name__ru   rC   rO   r   rA   rA   rA   rB   <module>   s    
T