
    Vhb-                        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r
d dlZd dlmZ  ej                  e      Z	 d		 	 	 	 	 	 	 	 	 	 	 d
dZd Z	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)    )annotationsN)IOTYPE_CHECKING)_type_utils)FileLikec                   ddl }|3t        j                  j                  |j                  j
                        n(t        j                  j                  | j                        }|<|j                         | j                  k7  r| j                  |j                               }  |j                         }||_
        |j                         |_        |j                  j                  | j                         |j                  j                   |_        |d| j%                         j'                         d}|j)                         D ]6  \  }	}
|j*                  j-                         }|	|_        t1        |
      |_        8 t4        j6                  j9                  ||      }t4        j6                  j;                  |      rt5        j<                  |       t4        j6                  j?                  |      }t4        j6                  j;                  |      st5        j@                  |       tC        |d      5 }|jE                  | jG                  d      jI                                ddd       |S # 1 sw Y   |S xY w)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)locationoffsetlengthxbT)force)%onnxjit_type_utilsJitScalarTypefrom_onnx_typetensor_type	elem_type
from_dtypedtypetoTensorProtoname	onnx_type	data_typedimsextendshapeEXTERNALdata_locationuntyped_storagenbytesitemsexternal_dataaddkeystrvalueospathjoinexistsremovedirnamemakedirsopenwritenumpytobytes)tensorr   r	   basepathdtype_overrider   scalar_typetensor_protokey_value_pairskventryexternal_data_file_pathexternal_data_dir_path	data_files                  U/home/dcms/DCMS/lib/python3.12/site-packages/torch/onnx/_internal/fx/serialization.py'_create_tensor_proto_with_external_datar@      s   6  % 	$$33&&00	
 ))44V\\B  !k&7&7&9V\\&I;,,./#4##%LL(224LV\\*!%!1!1!:!:L
 ((*113O
  %%' 1**..0	!f !ggll8X>	ww~~-.
		)*  WW__-DE77>>01 	*+ 
%t	, <	 	4088:;	< < s   ,0I&&I0c                    ddl m} i } || dd      5 }|j                         D ]$  }|j                  |      j	                         ||<   & 	 d d d        |S # 1 sw Y   |S xY w)Nr   )	safe_openptcpu)	frameworkdevice)safetensorsrB   keys
get_tensorrD   )safetensors_filerB   tensorsfr9   s        r?   $_convert_safetensors_to_torch_formatrM   i   sh     &G	#tE	B /a 	/Aa,,.GAJ	// N/ Ns   8AA!c                   ddl }i }t        |j                  j                        D 	ci c]  \  }}	|	j                  | }
}}	|j                  j
                  D ch c]  }|j                   }}|D ]  }t        |t              r|}nit        |t        t        j                  f      r0t        j                  |      j                  d      rt        |      }n	 t        j                  |dd      }|j5                         D ]  \  }}|r|j7                  d
d      }||v r|j9                  |       n>|D ]9  }|j                  |      s|j                  |      s&|}|j9                  |        n t        j:                  j=                  ||      }|j                  j
                  D 	ci c]  }	|	j                  |	j>                   }}	||
v r|||
|   <   tA        |||| |jC                  |d            }|j                  j                  jE                  |         t        tG        |j5                         d            }|jI                         D ]  }|j                  j                  |=   |jJ                  |t        j:                  j=                  | |             yc c}	}w c c}w # t         t"        f$ r}dt        |      v s@t        |t$        j&                  t(        f      r~|j+                         rn|j-                         r^t.        j1                  d       t        |t$        j&                  t(        f      r|j3                  d       t        j                  |d	      }n|Y d}~|d}~ww xY wc c}	w )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   Nz.safetensorsrD   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.)rO   ._)reverse)&r   	enumerategraphinitializerr   input
isinstancedictr&   r(   PathLikefspathendswithrM   torchloadRuntimeError
ValueErrorioIOBaser   readableseekablelogwarningseekr"   replacer,   r)   r*   typer@   popappendsortedrH   save)r4   model_locationinitializer_locationtorch_state_dicts
onnx_modelrename_initializerr   initializers_to_be_deletedidxr9   existing_initializersrW   onnx_input_namesel
state_dicter   r3   onnx_input_namerelative_tensor_file_pathmodel_input_typesr7   s                         r?   save_model_with_external_datar}   v   s&   N !#"+J,<,<,H,H"IQ  1;0@0@0F0FGu

GG M>b$ J"sBKK01biim6L6L7 B"E
  "'BU!NJ" ',,. .	>LD&!
 ||C- '' ''-'7 O&//59W  /(//@ )+5I4(P% :D9I9I9O9O PA P P ,,JN*+@+FGB)!%%dD1L ((//=].	>?M>^ "&)//14@" *..0 .((-. DIIj"'',,x@Au H  %j1  DAN"2		27KKMKKMz &b299b/:GGAJ%*ZZ%G
 # b !Qs*   J!J'J,)M6,M3;B-M..M3)N)r3   ztorch.Tensorr   r&   r	   r&   r4   r&   r5   zonnx.TypeProto | Nonereturnzonnx.TensorProto)F)r4   r&   rn   r&   ro   r&   rp   ztuple[dict | FileLike, ...]rq   zonnx.ModelProtorr   boolr~   None)
__future__r   ra   loggingr(   typingr   r   r]   
torch.onnxr   r   r   torch.typesr   	getLogger__name__re   r@   rM   r}        r?   <module>r      s    " 	  	 $  4 $g! -1QQ
Q Q 	Q
 *Q Qh	&  %DBDBDB DB 3	DB
  DB DB 
DBr   