
    sg,                        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Zd dlm	Z
 erd dlZ ej                  e      Z	 d	 	 	 	 	 	 	 	 	 	 	 d	dZd Z	 d
	 	 	 	 	 	 	 	 	 	 	 	 	 ddZy)    )annotationsN)TYPE_CHECKING)_type_utilsc                   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                  X/var/www/html/venv/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)safetensorsr@   keys
get_tensorrB   )safetensors_filer@   tensorsfr7   s        r=   $_convert_safetensors_to_torch_formatrK   g   sh     &G	#tE	B /a 	/Aa,,.GAJ	// N/ Ns   8AA!c                X   ddl }i }t        |j                  j                        D 	ci c]  \  }}	|	j                  | }
}}	|j                  j
                  D ch c]  }|j                   }}|D ]  }t        |t              r|}nFt        |t              r|j                  d      rt        |      }n	 t        j                  |dd      }|j)                         D ]  \  }}|r|j+                  d
d      }||v r|j-                  |       n>|D ]9  }|j                  |      s|j                  |      s&|}|j-                  |        n t.        j0                  j3                  ||      }|j                  j
                  D 	ci c]  }	|	j                  |	j4                   }}	||
v r|||
|   <   t7        |||| |j9                  |d            }|j                  j                  j;                  |         t        t=        |j)                         d            }|j?                         D ]  }|j                  j                  |=   |j@                  |t.        j0                  j3                  | |             yc c}	}w c c}w # t        t        f$ r}dt        |      v st        |t        j                         rXt"        j%                  d       t        |t        j                         r|j'                  d       t        j                  |d	      }n|Y d}~Pd}~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.safetensorsrB   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.)rM   ._)reverse)!r   	enumerategraphinitializerr   input
isinstancedictr$   endswithrK   torchloadRuntimeError
ValueErrorioBytesIOlogwarningseekr    replacer*   r&   r'   r(   typer>   popappendsortedrF   save)r2   model_locationinitializer_locationtorch_state_dicts
onnx_modelrename_initializerr   initializers_to_be_deletedidxr7   existing_initializersrU   onnx_input_namesel
state_dicter   r1   onnx_input_namerelative_tensor_file_pathmodel_input_typesr5   s                         r=   save_model_with_external_datarw   t   s   N !#"+J,<,<,H,H"IQ  1;0@0@0F0FGu

GG I>b$ J"c"r{{>'BA"E
  "'BU!NJ ',,. .	>LD&!
 ||C- '' ''-'7 O&//59W  /(//@ )+5I4(P% :D9I9I9O9O PA P P ,,JN*+@+FGB)!%%dD1L ((//=].	>7I>V "&)//14@" *..0 .((-. DIIj"'',,x@Am H %j1  DI #B

3z &b"**5GGAJ%*ZZ%G
 # ^ !Qs*   I>J7J	L'	L$BLL$)N)r1   ztorch.Tensorr   r$   r   r$   r2   r$   r3   zonnx.TypeProto | Nonereturnzonnx.TensorProto)F)r2   r$   rh   r$   ri   r$   rj   z#tuple[dict | str | io.BytesIO, ...]rk   zonnx.ModelProtorl   boolrx   None)
__future__r   r]   loggingr&   typingr   rY   
torch.onnxr   r   r   	getLogger__name__r_   r>   rK   rw        r=   <module>r      s    " 	  	    4 g! -1QQ
Q Q 	Q
 *Q Qh	&  %@B@B@B @B ;	@B
  @B @B 
@Br   