o
    wZhb-                     @  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_utilsZJitScalarTypeZfrom_onnx_typeZtensor_typeZ	elem_typeZ
from_dtypeZdtypetoZTensorProtor	   Z	onnx_typeZ	data_typedimsextendshapeZEXTERNALZdata_locationZuntyped_storagenbytesitemsZexternal_dataaddkeyr
   valueospathjoinexistsremovedirnamemakedirsopenwritenumpytobytes)r   r	   r   r   r   r   Zscalar_typetensor_protoZkey_value_pairskventryZexternal_data_file_pathZexternal_data_dir_pathZ	data_file r/   T/var/www/auris/lib/python3.10/site-packages/torch/onnx/_internal/fx/serialization.py'_create_tensor_proto_with_external_data   sD   






r1   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)Z	frameworkZdevice)Zsafetensorsr2   keysZ
get_tensorr4   )Zsafetensors_filer2   Ztensorsfr,   r/   r/   r0   $_convert_safetensors_to_torch_formati   s   
r7   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 r/   r	   ).0idxr,   r/   r/   r0   
<dictcomp>   s    z1save_model_with_external_data.<locals>.<dictcomp>c                 S  s   h | ]}|j qS r/   rA   )rB   inputr/   r/   r0   	<setcomp>   s    z0save_model_with_external_data.<locals>.<setcomp>z.safetensorsr4   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.)rG   ._c                 S  s   i | ]}|j |jqS r/   )r	   type)rB   r,   r/   r/   r0   rD      s    )reverse)$r   	enumerategraphZinitializerrE   
isinstancedictr
   r    PathLikefspathendswithr7   torchloadRuntimeError
ValueErrorioIOBaser   readableseekablelogwarningseekr   replacer$   r!   r"   r1   popappendsortedr5   save)r   r8   r9   r:   r<   r>   r   Zinitializers_to_be_deletedZexisting_initializersZonnx_input_nameselZ
state_dicter	   r   Zonnx_input_nameZrelative_tensor_file_pathZmodel_input_typesr+   rC   r/   r/   r0   save_model_with_external_datav   s~   '





0rf   )N)r   r   r	   r
   r   r
   r   r
   r   r   r   r   )F)r   r
   r8   r
   r9   r
   r:   r;   r<   r=   r>   r?   r   r@   )
__future__r   rX   loggingr    typingr   r   rT   Z
torch.onnxr   r   r   Ztorch.typesr   	getLogger__name__r\   r1   r7   rf   r/   r/   r/   r0   <module>   s    
T