o
    q::j=                     @  s  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mZ d dl	m
Z
mZ d dlmZ d dlm  mZ d dlmZmZmZmZmZ erOd dlmZmZ d[ddZeh dZeeZdZ dZ!G dd dZ"d\ddZ#d]dd Z$d^d#d$Z%				d_d`d+d,Z&	-		.	/dadbd3d4Z'dcd5d6Z(ddd8d9Z)ded<d=Z*dfdBdCZ+dgdFdGZ,dedHdIZ-dhdLdMZ.dedNdOZ/didQdRZ0djdSdTZ1dkdVdWZ2dldYdZZ3dS )m    )annotationsN)chain)IOTYPE_CHECKING)AttributeProtoFunctionProto
GraphProto
ModelProtoTensorProto)CallableIterablebase_dirstrlocationtensor_name	read_onlyboolreturnintc                 C  s   t | |||S )z<Open external data via C++ and return a CRT file descriptor.)	c_checker_open_external_data)r   r   r   r    r   `/home/nk/hobo-godmode/plappi-mvp/.venv/lib/python3.10/site-packages/onnx/external_data_helper.py_open_external_data_fd   s   r   >   lengthoffsetbasepathchecksumr   
   d   c                   @  s   e Zd ZdddZdS )	ExternalDataInfotensorr
   r   Nonec           	      C  sd  d| _ d | _d | _d | _d| _t }d}|jD ]1}|jtv r't	| |j|j
 q|d7 }t|tk rH|jd t }t|jtkrC|d7 }|| q|rvt|}|t| }t|}|dkre|d| d7 }tjd| d|jd	t d
d | jd urt| j| _| jdk rtd| j d|j| jd urt| j| _| jdk rtd| j d|jd S d S )N r      z...z and z morez&Ignoring unknown external data key(s) z for tensor z. Allowed keys:    )
stacklevelz/External data offset must be non-negative, got z/External data length must be non-negative, got )r   r   r   r   r   setexternal_datakey_ALLOWED_EXTERNAL_DATA_KEYSsetattrvaluelen_MAX_UNKNOWN_KEYS_IN_WARNING_MAX_KEY_DISPLAY_LENGTHaddsortedreprwarningswarnname_SORTED_ALLOWED_KEYSr   
ValueError)	selfr!   unknown_keysunknown_key_countentry	truncatedshownextrakey_listr   r   r   __init__:   sb   








zExternalDataInfo.__init__N)r!   r
   r   r"   )__name__
__module____qualname__r@   r   r   r   r   r    9   s    r    	data_file	IO[bytes]infobytesc              	   C  s   t |  j}|jdur&|j|kr td|j d| d|| |j |jdurU|jdur3|jnd}|| }|j|krOtd|j d| d| d|| |jS |  S )	a  Validate offset/length against actual file size and read data.

    Layer 3 defense-in-depth (CWE-400): prevents memory exhaustion even if the
    model was crafted via direct protobuf APIs that bypass Python parsing.

    Returns the raw bytes read from the file.
    NzExternal data offset (z) exceeds file size (z) for tensor r   zExternal data length (z) exceeds available data (z bytes from offset )	osfstatfilenost_sizer   r7   seekr   read)rD   rF   r   	file_size
read_start	availabler   r   r   #_validate_external_data_file_boundsm   s4   





rQ   r!   r
   r"   c                 C  s\   t | }t||j| jd}t|d}t||| j| _W d   dS 1 s'w   Y  dS )zLoads data from an external file for tensor.
    Ideally TensorProto should not hold any raw data but if it does it will be ignored.

    Arguments:
        tensor: a TensorProto object.
        base_dir: directory that contains the external data.
    TrbN)r    r   r   r5   rH   fdopenrQ   raw_data)r!   r   rF   fdrD   r   r   r   load_external_data_for_tensor   s   "rV   modelr	   c                 C  s8   t | D ]}t|rt|| tj|_|jdd= qdS )zLoads external tensors into model

    Arguments:
        model: ModelProto to load external data to
        base_dir: directory that contains external data
    N)_get_all_tensorsuses_external_datarV   r
   DEFAULTdata_locationr(   )rW   r   r!   r   r   r   load_external_data_for_model   s   
r\   r   
int | Noner   r   
str | Noner   c           	      C  s   |  dstd| j d| jd d = tj| _||d ur!t|nd |d ur*t|nd ||d D ]\}}|d urG| j	 }||_
t||_q2d S )NrT   zTensor zH does not have raw_data field. Cannot set external data for this tensor.)r   r   r   r   r   )HasFieldr7   r5   r(   r
   EXTERNALr[   r   itemsr0   r)   r   r,   )	r!   r   r   r   r   r   kvr;   r   r   r   set_external_data   s(   



rd   T   Fall_tensors_to_one_filesize_thresholdconvert_attributec           	      C  s   t | }|r
t| }|rItt d }|r0tj|r tdtj	|r.t
d| d|}|D ]}|drFt|j|krFt|| q2dS |D ]!}|drlt|j|krl|j}t|sgtt }t|| qKdS )a  Call to set all tensors with raw data as external data. This call should precede 'save_model'.
    'save_model' saves all the tensors data as external data after calling this function.

    Arguments:
        model (ModelProto): Model to be converted.
        all_tensors_to_one_file (bool): If true, save all tensors to one external file specified by location.
            If false, save each tensor to a file named with the tensor name.
        location: specify the external file relative to the model that all tensors to save to.
            Path is relative to the model path.
            If not specified, will use the model name.
        size_threshold: Threshold for size of data. Only when tensor's data is >= the size_threshold
            it will be converted to external data. To convert every tensor with raw data to external data set size_threshold=0.
        convert_attribute (bool): If true, convert all tensors to external data
                       If false, convert only non-attribute tensors to external data

    Raise:
        ValueError: If location is not a relative path.
        FileExistsError: If a file already exists in location.
    z.datazDlocation must be a relative path that is relative to the model path.zExternal data file exists in .rT   N)_get_initializer_tensorsrX   r   uuiduuid1rH   pathisabsr7   existsFileExistsErrorr_   sys	getsizeofrT   rd   r5   _is_valid_filename)	rW   rf   r   rg   rh   tensors	file_namer!   tensor_locationr   r   r   convert_model_to_external_data   s<   

rw   c                 C  s@   t | D ]}t|r|dstd|jdd= tj|_qdS )zCall to set all tensors which use external data as embedded data.
    save_model saves all the tensors data as embedded data after
    calling this function.

    Arguments:
        model (ModelProto): Model to be converted.
    rT   raw_data field doesn't exist.N)rX   rY   r_   r7   r(   r
   rZ   r[   )rW   r!   r   r   r    convert_model_from_external_data  s   
ry   	base_pathc                 C  s   t | }| dstdt||j| jd}t|dC}|	dd |j
durB| }|j
|kr<|d|j
|   |	|j
 | }|| j t| |j|| |  W d   dS 1 scw   Y  dS )	a  Writes tensor data to an external file according to information in the `external_data` field.
    The function checks the external is a valid name and located in folder `base_path`.

    Arguments:
        tensor (TensorProto): Tensor object to be serialized
        base_path: System path of a folder where tensor data is to be stored

    Raises:
        ValueError: If the external file is invalid.
    rT   rx   Fzr+br   r%   N    )r    r_   onnx_checkerValidationErrorr   r   r5   rH   rS   rL   r   tellwriterT   rd   )r!   rz   rF   rU   rD   rN   r   r   r   r   save_external_data  s   



"r   onnx_model_protoIterable[TensorProto]c                 C  s   t t| t| S )z=Scan an ONNX model for all tensors and return as an iterator.)r   rj   _get_attribute_tensorsr   r   r   r   rX   5  s   rX   	attributer   func-Callable[[GraphProto], Iterable[TensorProto]]c                 c  sL    | j tjkr|| jE dH  | j tjkr"| jD ]}||E dH  qdS dS )zICreate an iterator through processing ONNX model attributes with functor.N)typer   GRAPHgGRAPHSgraphs)r   r   graphr   r   r   _recursive_attribute_processor=  s   
r   r   r   c                c  s:    | j E dH  | jD ]}|jD ]
}t|tE dH  qq
dS )z@Create an iterator of initializer tensors from ONNX model graph.N)initializernoder   r   #_get_initializer_tensors_from_graph)r   r   r   r   r   r   r   H  s   

r   c                 c  s    t | jE dH  dS )z:Create an iterator of initializer tensors from ONNX model.N)r   r   r   r   r   r   rj   R  s   rj   graph_or_functionGraphProto | FunctionProtoc                c  sL    | j D ]}|jD ]}|dr|jV  |jE dH  t|tE dH  q	qdS )zSCreate an iterator of tensors from node attributes of an ONNX model graph/function.tN)r   r   r_   r   rt   r   !_get_attribute_tensors_from_graph)r   r   r   r   r   r   r   W  s   


r   c                 c  s0    t | jE dH  | jD ]	}t |E dH  qdS )zDCreate an iterator of tensors from node attributes of an ONNX model.N)r   r   	functions)r   functionr   r   r   r   e  s
   
r   filenamec                 C  s   t d}|| }t|S )z8Utility to check whether the provided filename is valid.z^[^<>:;,?"*|/]+$)recompilematchr   )r   expr   r   r   r   rs   l  s   

rs   c                 C  s   |  do
| jtjkS )z?Returns true if the tensor stores data in an external location.r[   )r_   r[   r
   r`   )r!   r   r   r   rY   s  s   

rY   	field_keyc                 C  s*   t | jD ]\}}|j|kr| j|= qdS )a  Removes a field from a Tensor's external_data key-value store.

    Modifies tensor object in place.

    Arguments:
        tensor (TensorProto): Tensor object from which value will be removed
        field_key (string): The key of the field to be removed
    N)	enumerater(   r)   )r!   r   ifieldr   r   r   remove_external_data_field{  s
   	
r   filepathc                 C  s8   t | D ]}t|r|drt|| |d q| S )a  Serializes data for all the tensors which have data location set to TensorProto.External.

    Note: This function also strips basepath information from all tensors' external_data fields.

    Arguments:
        model (ModelProto): Model object which is the source of tensors to serialize.
        filepath: System path to the directory which should be treated as base path for external data.

    Returns:
        ModelProto: The modified model object.
    rT   )rX   rY   r_   r   
ClearField)rW   r   r!   r   r   r   write_external_data_tensors  s   

r   )
r   r   r   r   r   r   r   r   r   r   )rD   rE   rF   r    r   r   r   rG   )r!   r
   r   r   r   r"   )rW   r	   r   r   r   r"   )NNNN)r!   r
   r   r   r   r]   r   r]   r   r^   r   r^   r   r"   )TNre   F)rW   r	   rf   r   r   r^   rg   r   rh   r   r   r"   )rW   r	   r   r"   )r!   r
   rz   r   r   r"   )r   r	   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r!   r
   r   r   )r!   r
   r   r   r   r"   )rW   r	   r   r   r   r	   )4
__future__r   rH   r   rq   rk   r3   	itertoolsr   typingr   r   onnx.checkercheckerr|   onnx.onnx_cpp2py_export.checkeronnx_cpp2py_exportr   onnx.onnx_pbr   r   r   r	   r
   collections.abcr   r   r   	frozensetr*   r1   r6   r.   r/   r    rQ   rV   r\   rd   rw   ry   r   rX   r   r   rj   r   r   rs   rY   r   r   r   r   r   r   <module>   s\   

4
#

:










