o
    Ďi/                     @  sL  d dl m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	 d dl
m  mZ d dlmZmZmZmZmZ e	rCd dlmZmZ G dd dZdLddZdMddZ				dNdOddZ				 dPdQd&d'ZdRd(d)ZdSd+d,ZdTd/d0ZdUd5d6ZdVd9d:Z dTd;d<Z!dVd=d>Z"dTd?d@Z#dWdBdCZ$dXdDdEZ%dYdGdHZ&dZdJdKZ'dS )[    )annotationsN)chain)TYPE_CHECKING)AttributeProtoFunctionProto
GraphProto
ModelProtoTensorProto)CallableIterablec                   @  s   e Zd ZdddZdS )	ExternalDataInfotensorr	   returnNonec                 C  sf   d| _ d | _d | _d | _d| _|jD ]
}t| |j|j q| jr&t	| j| _| jr1t	| j| _d S d S )N )
locationoffsetlengthchecksumbasepathexternal_datasetattrkeyvalueint)selfr   entry r   U/home/jeff/fluffinator/venv/lib/python3.10/site-packages/onnx/external_data_helper.py__init__   s   
zExternalDataInfo.__init__N)r   r	   r   r   )__name__
__module____qualname__r   r   r   r   r   r      s    r   r   r	   base_dirstrr   r   c                 C  s   t | }t||j| j}t|d*}|jr||j |jr'|	|j| _
n|	 | _
W d   dS 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.
    rbN)r   	c_checker_resolve_external_data_locationr   nameopenr   seekr   readraw_data)r   r#   infoexternal_data_file_path	data_filer   r   r   load_external_data_for_tensor,   s   
"r0   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_datar0   r	   DEFAULTdata_locationr   )r1   r#   r   r   r   r   load_external_data_for_modelB   s   
r6   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 )Nr,   zTensor zGdoes not have raw_data field. Cannot set external data for this tensor.)r   r   r   r   r   )HasField
ValueErrorr(   r   r	   EXTERNALr5   r   itemsaddr   r$   r   )	r   r   r   r   r   r   kvr   r   r   r   set_external_dataR   s0   



r@   T   Fall_tensors_to_one_fileboolsize_thresholdr   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 .r,   N)_get_initializer_tensorsr2   r$   uuiduuid1ospathisabsr:   existsFileExistsErrorr9   sys	getsizeofr,   r@   r(   _is_valid_filename)	r1   rB   r   rD   rE   tensors	file_namer   tensor_locationr   r   r   convert_model_to_external_datap   s<   

rU   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.
    r,   raw_data field doesn't exist.N)r2   r3   r9   r:   r   r	   r4   r5   )r1   r   r   r   r    convert_model_from_external_data   s   
rW   	base_pathc                 C  s  t | }tj||j}| dstdtj|s0t|d W d   n1 s+w   Y  t|dC}|	dd |j
durZ| }|j
|krT|d|j
|   |	|j
 | }|| j t| |j|| |  W d   dS 1 s{w   Y  dS )	zWrites tensor data to an external file according to information in the `external_data` field.

    Arguments:
        tensor (TensorProto): Tensor object to be serialized
        base_path: System path of a folder where tensor data is to be stored
    r,   rV   abNzr+br          )r   rJ   rK   joinr   r9   r:   isfiler)   r*   r   tellwriter,   r@   )r   rX   r-   r.   r/   	file_sizer   r   r   r   save_external_data   s&   


"ra   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   rG   _get_attribute_tensors)rb   r   r   r   r2      s   r2   	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)re   rf   graphr   r   r   _recursive_attribute_processor   s   
rn   graph_or_functionGraphProto | FunctionProtoc                c  sD    t | tr| jE dH  | jD ]}|jD ]
}t|tE dH  qqdS )zICreate an iterator of initializer tensors from ONNX model graph/function.N)
isinstancer   initializernodere   rn   #_get_initializer_tensors_from_graphro   rs   re   r   r   r   rt      s   


rt   c                 c  s0    t | jE dH  | jD ]	}t|E dH  qdS )z:Create an iterator of initializer tensors from ONNX model.N)rt   rm   	functions!_get_attribute_tensors_from_graphrb   functionr   r   r   rG      
   
rG   c                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)rs   re   r9   r{   rR   rn   rw   ru   r   r   r   rw     s   


rw   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)rw   rm   rv   rx   r   r   r   rd     rz   rd   filenamec                 C  s   t d}|| }t|S )z8Utility to check whether the provided filename is valid.z^[^<>:;,?"*|/]+$)recompilematchrC   )r|   expr   r   r   r   rQ     s   

rQ   c                 C  s   |  do
| jtjkS )z?Returns true if the tensor stores data in an external location.r5   )r9   r5   r	   r;   )r   r   r   r   r3     s   

r3   	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.
    r,   )r2   r3   r9   ra   
ClearField)r1   r   r   r   r   r   write_external_data_tensors5  s   

r   )r   r	   r#   r$   r   r   )r1   r   r#   r$   r   r   )NNNN)r   r	   r   r$   r   r7   r   r7   r   r8   r   r8   r   r   )TNrA   F)r1   r   rB   rC   r   r8   rD   r   rE   rC   r   r   )r1   r   r   r   )r   r	   rX   r$   r   r   )rb   r   r   rc   )re   r   rf   rg   r   rc   )ro   rp   r   rc   )r|   r$   r   rC   )r   r	   r   rC   )r   r	   r   r$   r   r   )r1   r   r   r$   r   r   )(
__future__r   rJ   r}   rO   rH   	itertoolsr   typingr   onnx.onnx_cpp2py_export.checkeronnx_cpp2py_exportcheckerr&   onnx.onnx_pbr   r   r   r   r	   collections.abcr
   r   r   r0   r6   r@   rU   rW   ra   r2   rn   rt   rG   rw   rd   rQ   r3   r   r   r   r   r   r   <module>   sH   

 
:

"







