
    
Ng1                        d Z ddlmZ ddlZddlZddlmZmZ ddlZ	ddl
Z
ddlmZ ddlZ
ddlmc mZ 	 	 	 	 d"d#dZd Zd$dZ G d d          Z	 d%d&d!ZdS )'zXImplements function make_large_model to easily create and save models
bigger than 2 Gb.
    )annotationsN)AnyIterabletensoronnx.TensorProtolocationstroffset
int | Nonelengthchecksum
str | NonebasepathreturnNonec                    | j         d d = t          j        j        | _        |||||d                                D ];\  }}|4| j                                         }||_        t          |          |_	        <d S )N)r   r
   r   r   r   )
external_dataonnxTensorProtoEXTERNALdata_locationitemsaddkeyr	   value)	r   r   r
   r   r   r   kventrys	            P/var/www/html/ai-engine/env/lib/python3.11/site-packages/onnx/model_container.py_set_external_datar       s     	QQQ+4F  egg
! 
!1 =(,,..EEIa&&EK
! 
!    c              #     K   | j         D ]6}|j        D ],}|j        r#|j        V  t          |j                  E d {V  -7d S N)node	attributeg_enumerate_subgraphs)graphr$   atts      r   r'   r'   ,   so      
 7 7> 	7 	7Cu 7e/666666666	77 7r!   tensor_nametensor_typeintshapetuple[int, ...]c                    | }t          j                    }||_        t          ||           ||_        |j                            |           |S )a  Create an external tensor.

    Arguments:
        location: unique identifier (not necessary a path)
        tensor_name: tensor name in the graph
        tensor_type: onnx type
        shape: shape the of the initializer

    Returns:
        the created tensor
    )r   r   namer    	data_typedimsextend)r   r*   r+   r-   tensor_locationr   s         r   make_large_tensor_protor5   4   sQ     OFFKv///"F
KuMr!   c                      e Zd ZdZd Zd ZddZed d
            Zej	        d!d            Zd"dZ
d#dZd$dZd Zd%dZ	 d&d%dZd'd(dZd ZdS ))ModelContainera  Implements an API to store large tensors outside the main ModelProto,
    it avoids copying large initializers when defining the model and these initializers
    are never serialized through protobuf.
    No tensor is stored on disk until the user explicitly saves the model.
    c                "    d | _         i | _        d S r#   )model_proto_large_initializersselfs    r   __init__zModelContainer.__init__R   s    489;r!   c                `    | j         &t          j                            | j                    d S d S r#   )model_protor   checkercheck_modelr;   s    r   rA   zModelContainer.check_modelV   s2    'L$$T%566666 ('r!   r0   r	   r   
np.ndarrayc                ~    || j         vr(t          d|dt          | j                    d          | j         |         S )z*Returns an external tensor given its name.zUnable to find large tensor z among .)r:   
ValueErrorsortedr<   r0   s     r   __getitem__zModelContainer.__getitem__Z   sS    t...`t``fTE\>]>]```   &t,,r!   onnx.ModelProtoc                <    | j         t          d          | j         S )NzModelContainer is empty.)r9   RuntimeErrorr;   s    r   r?   zModelContainer.model_protob   s#    $9:::  r!   r?   c                `    || _         t          |                                           | _        d S r#   )r9   listenumerate_graph_protosgraphs_)r<   r?   s     r   r?   zModelContainer.model_protoh   s)    'D7799::r!   Iterable[onnx.GraphProto]c              #  d   K   | j         j        V  t          | j         j                  E d{V  dS )z&Enumerates all GraphProtos in a model.N)r?   r(   r'   r;   s    r   rN   z%ModelContainer.enumerate_graph_protosm   sD      $$$$'(8(>???????????r!   boolc                ,    |                     d          S )zTells if an initializer name is an external initializer stored in memory.
        The name must start with '#' in that case.
        #)
startswithrG   s     r   !is_in_memory_external_initializerz0ModelContainer.is_in_memory_external_initializerr   s     s###r!   r:   dict[str, np.ndarray]c                n    |D ]*}|                      |          st          d|d          +|| _        dS )z1Adds all large tensors (not stored in the model).zThe location z2 must start with '#' to be ignored by check model.N)rV   rE   r:   )r<   r:   r   s      r   set_large_initializersz%ModelContainer.set_large_initializersx   s\    # 	 	A99!<<  [A[[[   #5r!   c                T   t          j        | j                  D ]}t          j        |          sd }|j        D ]}|j        dk    r|}|t          d|j        d          |j        | j	        vr5t          d|j        d|j        dt          | j	                   d          d S )Nr   "No location found for tensor name rD   "Unable to find large tensor named  with location  in )ext_data_get_all_tensorsr?   uses_external_datar   r   rK   r0   r   r:   rF   )r<   r   propexts       r   check_large_initializersz'ModelContainer.check_large_initializers   s    /0@AA 	 	F.v66 7;D+  7j((D|"IIII   z!888": : :%)Z: :d566: : :   9	 	r!   	file_pathall_tensors_to_one_filec                   dd}i }t           j                            |          }t           j                            |          st	          d|d	          | j                                        }t          j                    }|	                    |           t           j        
                    t           j                            |          d
                   d         }|rXt           j                            |          d          d}	| d}
d}t          |
d          5 }	 ddd           n# 1 swxY w Y   t          j        |          D ]}t          j        |          sd}|j        D ]}|j        dk    r|}|t%          d|j        d          |j        | j        vr5t%          d|j        d|j        dt-          | j                   d          | j        |j                 }t.          j        dk    r'|                                                                }n|                                }|rqt7          ||	|t9          |                     |t9          |          z  }t          |
d          5 }|                    |           ddd           n# 1 swxY w Y   ^ |||j        |           d}t7          ||           t           j                            ||          }||_        t          |d          5 }|                    |           ddd           n# 1 swxY w Y   t          |d          5 }|                    |                                           ddd           n# 1 swxY w Y   |S )a  Save the large model into a main onnx file and one file
        per tensor. Follows the same format as :func:`write_external_data_tensors
        <onnx.external_data_helper.write_external_data_tensors>`.
        The main model needs to be modified to update the file location,
        the function returns this modified copy.

        Arguments:
            file_path: model file
            all_tensors_to_one_file: all tensors in one file

        Returns:
            modified main model proto
        prefixr	   r0   unique_namesdict[str, int]r   c                    | r|  d| }dD ]}|                     |d          }|}||v r||         dz   }|||<   | d| S d||<   |S )N-z:/\;,!    _)replace)rh   r0   ri   c	base_nameis         r   _clean_namez2ModelContainer._save_external.<locals>._clean_name   s     * ))4)) + +||Ar**I|## &*%&T"#))a)))!"LKr!   zFolder z does not exist.r   rn   z.weightwbNr   r[   rD   r\   r]   r^   big)r   r
   r   abr   )rh   r	   r0   r	   ri   rj   r   r	   )ospathdirnameexistsFileNotFoundErrorr?   SerializeToStringr   
ModelProtoParseFromStringsplitextsplitopenr_   r`   ra   r   r   rK   r0   r   r:   rF   sys	byteorderbyteswaptobytesr    lenwritejoin)r<   re   rf   rt   ri   folderprotocopyrh   file_weightfull_file_weightr
   fr   rb   rc   	np_tensortensor_bytesr0   	full_names                       r   _save_externalzModelContainer._save_external   s   "	 	 	 	 (*++w~~f%% 	J#$Hf$H$H$HIII 2244  U###!!"'--	":":2">??B" 	W]]955a8AAAK"+444F&--                /55 (	* (	*F.v66 7;D+  7j((D|"IIII   z!888": : :%)Z: :d566: : :  
 /
;I}%%(1133;;==(0022& *"(!|,,	    #l+++*D11 *QGGL)))* * * * * * * * * * * * * * * &+fdj,GGPPP"6D9999GLL66	!
)T** *aGGL)))* * * * * * * * * * * * * * * )T"" 	.aGGD**,,---	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.sH   "D00D47D4>J  J$	'J$	
L,,L0	3L0		(M==NNFc                0    |                      ||          S )a  Save the large model.
        The function returns a ModelProto,
        the current one if the model did not need any modification,
        a modified copy of it if it required changes such as giving file names
        to every external tensor.

        Arguments:
            file_path: model file
            all_tensors_to_one_file: saves all large tensors in one file or
                one file per lerge tensor

        Returns:
            the saved ModelProto
        )rf   )r   )r<   re   rf   s      r   savezModelContainer.save   s'    & ""/F # 
 
 	
r!   Tload_large_initializersc                n    t          j        |d          | _        |r|                     |           dS dS )av  Load the large model.

        Arguments:
            file_path: model file
            load_large_initializers: loads the large initializers,
                if not done, the model is incomplete but it can be used to
                look into the model without executing it and method
                :meth:`_load_large_initializers` can be used to load them later
        F)load_external_dataN)r   
load_modelr9   _load_large_initializers)r<   re   r   s      r   loadzModelContainer.load  sG     !OI%PPP" 	5)))44444	5 	5r!   c                   | j         t          d          i | _        t          j                            |          }t          t          j        | j                             D ]\  }}t          j	        |          st          j
        |          }t          j        ||j        |j                  }d| }t          ||           t!          |d          5 }|j        r|                    |j                   |j        r|                    |j                  n|                                }	t*          j                            |j                  }
t3          |j                  }t6          j        dk    r<t;          j        |	|
                                                               |          }n)t;          j        |	|
                               |          }|| j        |<   ddd           n# 1 swxY w Y   dS )zLoads large initializers.

        Arguments:
            file_path: model file, the weight are expected to be in the same folder as this file
        Nz2A model must be loaded before loading the weights.z#try   rbrw   )dtype)!r9   rK   r:   rz   r{   r|   	enumerater_   r`   ra   ExternalDataInfo	c_checker_resolve_external_data_locationr   r0   r    r   r
   seekr   readr   helpertensor_dtype_to_np_dtyper1   tupler2   r   r   np
frombufferr   reshape)r<   re   base_dirrs   r   infoexternal_data_file_pathr   	data_fileraw_datar   r-   r   s                r   r   z'ModelContainer._load_large_initializers  s    $STTT"$7??9--"8#<T=N#O#OPP 	9 	9IAv.v66 ,V44D&/&O$-' '# q((Cv4444-t44 9	; 0NN4;/// 48;TINN4;///INNDTDT  <<V=MNNfk**=E))he<<<EEGGOOPUVV I !#he D D D L LU S SI/8',%9 9 9 9 9 9 9 9 9 9 9 9 9 9 9	9 	9s   DG22G6	9G6	N)r0   r	   r   rB   )r   rI   )r?   rI   )r   rP   )r0   r	   r   rR   )r:   rW   )re   r	   rf   rR   r   rI   )F)T)re   r	   r   rR   )__name__
__module____qualname____doc__r=   rA   rH   propertyr?   setterrN   rV   rY   rd   r   r   r   r    r!   r   r7   r7   K   sB        < < <7 7 7- - - - ! ! ! X!
 ; ; ; ;@ @ @ @
$ $ $ $5 5 5 5  &Z Z Z Z~ ).
 
 
 
 
.5 5 5 5 5'9 '9 '9 '9 '9r!   r7   r(   onnx.GraphProtor:   dict[str, np.ndarray] | Nonekwargsr   c                    t          j        j        | fi |}t                      }||_        |r)|                    |           |                                 |S )ac  Construct a ModelContainer

    C API and Python API of protobuf do not operate without serializing
    the protos. This function uses the Python API of ModelContainer.

    Arguments:
        graph: *make_graph* returns
        large_initializers: dictionary `name: large tensor`,
            large tensor is any python object supporting the DLPack protocol,
            the ownership the tensor is transferred to the ModelContainer,
            the tensor must define method `tobytes` like numpy tensors
        **kwargs: any attribute to add to the returned instance

    Returns:
        ModelContainer
    )r   r   
make_modelr7   r?   rY   rd   )r(   r:   r   modellarge_models        r   make_large_modelr   ?  sf    * K"533F33E ""K#K /**+=>>>,,...r!   )NNNN)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   r7   )r   
__future__r   rz   r   typingr   r   numpyr   r   onnx.external_data_helperexternal_data_helperr_   onnx.helperonnx.onnx_cpp2py_export.checkeronnx_cpp2py_exportr@   r   r    r'   r5   r7   r   r   r!   r   <module>r      s>    # " " " " " 				 



                      , , , , , ,     3 3 3 3 3 3 3 3 3 ! ! ! ! !.7 7 7   .q9 q9 q9 q9 q9 q9 q9 q9l 8<      r!   