Ë
    cQêjÀÁ  ã                   ó˜   — d 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Zddl	Zddl
ZddlmZmZ  ej                  d«      Z G d„ d	«      Zy)
zClass for ONNX model.é    N)Údeque)ÚPathé   )ÚMAXIMUM_PROTOBUFÚfind_by_nameÚneural_compressorc                   ó²  — e Zd ZdZd„ Zd„ Zed„ «       Zed„ «       Zej                  d„ «       Zd„ Z
ed„ «       Zej                  d	„ «       Zed
„ «       Zed„ «       Zej                  d„ «       Zd„ Zd„ Zd„ Zed„ «       Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d „ Z!d!„ Z"d"„ Z#dLd#„Z$ed$„ «       Z%d%„ Z&ed&„ «       Z'd'„ Z(d(„ Z)dMd*„Z*dMd+„Z+dMd,„Z,d-„ Z-d.„ Z.d/„ Z/dLd0„Z0e1d1„ «       Z2dNd2„Z3e1d3„ «       Z4dNd4„Z5d5„ Z6dLd6„Z7dMd7„Z8d8„ Z9dLd9„Z:d:„ Z;d;„ Z<d<„ Z=d=„ Z>dMd>„Z?	 	 	 	 dOd?„Z@	 	 dNd@„ZAdA„ ZBdB„ ZC	 dPdC„ZDdD„ ZEdE„ ZFdF„ ZGdG„ ZHdMdH„ZIdQdI„ZJdJ„ ZKdK„ ZLy))RÚ	ONNXModelzBuild ONNX model.c                 ó–  — t        |t        «      s|nt        j                  |d¬«      | _        t        |t        «      sdn|| _        | j                  «        | j                  r3| j
                  €'|j                  dd«      st        j                  d«       | j                  rst        |t        «      rc|j                  dd«      rQt        j                  j                  | j                  t        j                  j                  | j
                  «      «       d| _        t        |t        «      rŒt        j                  j#                  t%        |«      j&                  j)                  d«      j+                  «       «      r=d	d
lm} |j1                  t%        |«      j&                  j+                  «       «      | _        i | _        i | _        i | _        | j9                  | j                  j:                  j<                  «       | j?                  | j                  j:                  j<                  «       i | _         | jC                  «        d| _"        y)a;  Initialize an ONNX model.

        Args:
            model (str or ModelProto): path to onnx model or loaded ModelProto model object.
            ignore_warning (bool): ignore large model warning. Default is False.
            load_external_data (bool): load external data for large model. Default is True.
        F)Úload_external_dataNÚignore_warningzPModel size > 2GB. Please use model path instead of onnx model object to quantizer   Túconfig.jsonr   )Ú
AutoConfig)#Ú
isinstanceÚstrÚonnxÚloadÚ_modelÚ_model_pathÚcheck_is_large_modelÚ_is_large_modelÚgetÚloggerÚwarningÚexternal_data_helperÚload_external_data_for_modelÚosÚpathÚdirnameÚ_configÚexistsr   ÚparentÚjoinpathÚas_posixÚtransformersr   Úfrom_pretrainedÚnode_name_counterÚ_output_name_to_nodeÚ_input_name_to_nodesÚ_get_input_name_to_nodesÚgraphÚnodeÚ_get_output_name_to_nodeÚ_graph_infoÚ_get_graph_infoÚ	_q_config)ÚselfÚmodelÚkwargsr   s       úz/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/onnxruntime/quantization/neural_compressor/onnx_model.pyÚ__init__zONNXModel.__init__)   s›  € ô $.¨e´SÔ#9‘e¼t¿y¹yÈÐchÔ?iˆŒÜ'1°%¼Ô'=™4À5ˆÔà×!Ñ!Ô#Ø×Ò D×$4Ñ$4Ð$<ÀVÇZÁZÐP`ÐbgÔEhÜ�N‰NÐmÔnà×Ò¤J¨u´cÔ$:¸v¿z¹zÐJ^Ð`dÔ?eÜ×%Ñ%×BÑBÀ4Ç;Á;ÔPR×PWÑPW×P_ÑP_Ð`d×`pÑ`pÓPqÔràˆŒÜ�eœSÔ!¤b§g¡g§n¡n´T¸%³[×5GÑ5G×5PÑ5PÐQ^Ó5_×5hÑ5hÓ5jÔ&kÝ/à%×5Ñ5´d¸5³k×6HÑ6H×6QÑ6QÓ6SÓTˆDŒLà!#ˆÔØ$&ˆÔ!Ø$&ˆÔ!Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Ô=Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Ô=ØˆÔØ×ÑÔØˆ�ó    c                 óÆ   — t        j                  | j                  j                  «      }t	        d„ |j
                  j                  «       D «       «      }|t        kD  | _        y)zCheck model > 2GB.c              3   ób   K  — | ]'  }|j                   €Œ|j                   j                  –— Œ) y ­w©N)Úconst_valueÚnbytes)Ú.0Úvs     r4   ú	<genexpr>z1ONNXModel.check_is_large_model.<locals>.<genexpr>M   s(   è ø€ ò 
Ø%&ÈAÏMÉMÑLeˆA�M‰M× Õ ñ
ùs   ‚/”/N)	ÚirÚ
from_protor   r+   ÚsumÚinitializersÚvaluesr   r   )r1   Úir_graphÚinitializer_sizes      r4   r   zONNXModel.check_is_large_modelJ   sQ   € ä—=‘= §¡×!2Ñ!2Ó3ˆÜñ 
Ø*2×*?Ñ*?×*FÑ*FÓ*Hô
ó 
Ðð  0Ô2BÑBˆÕr6   c                 ó   — | j                   S )z!Check the onnx model is over 2GB.)r   ©r1   s    r4   Úis_large_modelzONNXModel.is_large_modelR   s   € ð ×#Ñ#Ð#r6   c                 ó   — | j                   S )zReturn model path.©r   rG   s    r4   Ú
model_pathzONNXModel.model_pathW   ó   € ð ×ÑÐr6   c                 ó   — || _         y)zSet model path.NrJ   )r1   r   s     r4   rK   zONNXModel.model_path\   s   € ð  ˆÕr6   c                  ó   — y)zReturn framework.Úonnxruntime© rG   s    r4   Ú	frameworkzONNXModel.frameworka   s   € àr6   c                 ó   — | j                   S )zReturn q_config.©r0   rG   s    r4   Úq_configzONNXModel.q_confige   s   € ð �~‰~Ðr6   c                 ó   — || _         y)zSet q_config.NrS   )r1   rT   s     r4   rT   zONNXModel.q_configj   s   € ð "ˆ�r6   c                 ó   — | j                   S )z8Return huggingface config if model is Transformer-based.)r    rG   s    r4   Ú	hf_configzONNXModel.hf_configo   s   € ð �|‰|Ðr6   c                 ó   — | j                   S )zReturn model itself.)r   rG   s    r4   r2   zONNXModel.modelt   s   € ð �{‰{Ðr6   c                 ó  — || _         i | _        | j                  «        i | _        i | _        | j                  | j                   j                  j                  «       | j                  | j                   j                  j                  «       y)zSet model itself.N)	r   r.   r/   r(   r)   r*   r+   r,   r-   )r1   r2   s     r4   r2   zONNXModel.modely   sk   € ð ˆŒØˆÔØ×ÑÔØ$&ˆÔ!Ø$&ˆÔ!Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Ô=Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Õ=r6   c                 ó|   — | j                   j                  j                  D �cg c]  }|j                  ‘Œ c}S c c}w )zReturn input of model.)r   r+   ÚinputÚname©r1   Úis     r4   r[   zONNXModel.input„   s*   € à $§¡× 1Ñ 1× 7Ñ 7Ö8˜1�—“Ò8Ð8ùÒ8ó   £9c                 ó|   — | j                   j                  j                  D �cg c]  }|j                  ‘Œ c}S c c}w )zReturn output of model.)r   r+   Úoutputr\   r]   s     r4   ra   zONNXModel.outputˆ   s*   € à $§¡× 1Ñ 1× 8Ñ 8Ö9˜1�—“Ò9Ð9ùÒ9r_   c                 ó
  — i | _         | j                  «        i | _        i | _        | j	                  | j
                  j                  j                  «       | j                  | j
                  j                  j                  «       y)zUpdate model info.N)	r.   r/   r(   r)   r*   r   r+   r,   r-   rG   s    r4   ÚupdatezONNXModel.updateŒ   sb   € àˆÔØ×ÑÔØ$&ˆÔ!Ø$&ˆÔ!Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Ô=Ø×%Ñ% d§k¡k×&7Ñ&7×&<Ñ&<Õ=r6   c                 ó   — | j                   S )zEReturn ORT Graph Info object holding information about backend graph.)r.   rG   s    r4   Ú
graph_infozONNXModel.graph_info•   rL   r6   c                 ó°   — | j                   j                  j                  D ]3  }| j                  j	                  |j
                  |j                  i«       Œ5 y)zUpdate graph info.N)r   r+   r,   re   rc   r\   Úop_type©r1   r,   s     r4   r/   zONNXModel._get_graph_infoš   s@   € à—K‘K×%Ñ%×*Ñ*ò 	>ˆDØ�O‰O×"Ñ" D§I¡I¨t¯|©|Ð#<Õ=ñ	>r6   c           	      ó¤  — t         j                  j                  |«      d   dk7  rJt         j                  j                  t         j                  j                  |«      d   «      st	        d«      ‚| j
                  r�t        j                  j                  | j                  t         j                  j                  | j                  «      d   «       t        j                  | j                  |dd|j                  d«      d   dz   dd	¬
«       n t        j                  | j                  |«       | j                  �™t        | j                  d«      sdn| j                  j                  }|| j                  j                   _        t#        |«      j$                  j'                  d«      j)                  «       }| j                  j+                  |d	¬«       yy)zSave ONNX model.r   Ú z!"root" directory does not exists.Tú/éÿÿÿÿÚ_dataé   F©Úsave_as_external_dataÚall_tensors_to_one_fileÚlocationÚsize_thresholdÚconvert_attributeNÚ
model_typer   )Úuse_diff)r   r   Úsplitr!   Ú
ValueErrorrH   r   r   r   r   r   Ú
save_modelÚsaver    Úhasattrru   Ú	__class__r   r"   r#   r$   Úto_json_file)r1   Úrootru   Úoutput_config_files       r4   rz   zONNXModel.saveŸ   sR  € ä�7‰7�=‰=˜Ó˜qÑ! RÒ'´·±·±¼r¿w¹w¿}¹}ÈTÓ?RÐSTÑ?UÔ0VÜÐ@ÓAÐAØ×ÒÜ×%Ñ%×BÑBÀ4Ç;Á;ÔPR×PWÑPW×P]ÑP]Ð^b×^nÑ^nÓPoÐpqÑPrÔsÜ�O‰OØ—‘ØØ&*Ø(,ØŸ™ C›¨Ñ,¨wÑ6Ø#Ø"'öô �I‰I�d—k‘k 4Ô(à�<‰<Ð#Ü#*¨4¯<©<¸Ô#F™ÈDÏLÉL×LcÑLcˆJØ0:ˆD�L‰L×"Ñ"Ô-Ü!% d£×!2Ñ!2×!;Ñ!;¸MÓ!J×!SÑ!SÓ!UÐØ�L‰L×%Ñ%Ð&8À5Ð%ÕIð	 $r6   c                 óB   — | j                   j                  j                  S )zReturn model nodes.)r   r+   r,   rG   s    r4   ÚnodeszONNXModel.nodes·   s   € à�{‰{× Ñ ×%Ñ%Ð%r6   c                 óB   — | j                   j                  j                  S )zReturn model initializer.)r   r+   ÚinitializerrG   s    r4   rƒ   zONNXModel.initializer»   s   € à�{‰{× Ñ ×,Ñ,Ð,r6   c                 ó.   — | j                   j                  S )zReturn model graph.)r   r+   rG   s    r4   r+   zONNXModel.graph¿   s   € à�{‰{× Ñ Ð r6   c                 ó.   — | j                   j                  S )zReturn model ir_version.)r   Ú
ir_versionrG   s    r4   r†   zONNXModel.ir_versionÃ   s   € à�{‰{×%Ñ%Ð%r6   c                 ó.   — | j                   j                  S )zReturn model opset_import.)r   Úopset_importrG   s    r4   rˆ   zONNXModel.opset_importÇ   s   € à�{‰{×'Ñ'Ð'r6   c                 ó¨   — || j                   j                  j                  v r0| j                   j                  j                  j                  |«       yy)zRemove a node from model.N)r   r+   r,   Úremoverh   s     r4   Úremove_nodezONNXModel.remove_nodeË   s=   € à�4—;‘;×$Ñ$×)Ñ)Ñ)Ø�K‰K×Ñ×"Ñ"×)Ñ)¨$Õ/ð *r6   c                 ó4   — |D ]  }| j                  |«       Œ y)zRemove nodes from model.N)r‹   )r1   Únodes_to_remover,   s      r4   Úremove_nodeszONNXModel.remove_nodesÐ   s   € à#ò 	#ˆDØ×Ñ˜TÕ"ñ	#r6   c                 ód   — | j                   j                  j                  j                  |g«       y)zAdd a node to model.N©r   r+   r,   Úextendrh   s     r4   Úadd_nodezONNXModel.add_nodeÕ   s"   € à�‰×Ñ×Ñ×%Ñ% t fÕ-r6   c                 ób   — | j                   j                  j                  j                  |«       y)zAdd nodes to model.Nr�   )r1   Únodes_to_adds     r4   Ú	add_nodeszONNXModel.add_nodesÙ   s    € à�‰×Ñ×Ñ×%Ñ% lÕ3r6   c                 óÎ   — t        |j                  | j                  j                  j                  «      €1| j                  j                  j                  j                  |g«       yy)zAdd a initializer to model.N)r   r\   r   r+   rƒ   r‘   ©r1   Útensors     r4   Úadd_initializerzONNXModel.add_initializerÝ   sI   € ä˜Ÿ™ T§[¡[×%6Ñ%6×%BÑ%BÓCÐKØ�K‰K×Ñ×)Ñ)×0Ñ0°&°Õ:ð Lr6   c                 ó4   — |D ]  }| j                  |«       Œ y)zAdd initializers to model.N)r™   )r1   Útensorsr˜   s      r4   Úadd_initializerszONNXModel.add_initializersâ   s   € àò 	)ˆFØ× Ñ  Õ(ñ	)r6   c                 ót   — | j                   j                  j                  D ]  }|j                  |k(  sŒ|c S  y)zGet an initializer by name.N)r   r+   rƒ   r\   )r1   r\   r˜   s      r4   Úget_initializerzONNXModel.get_initializerç   s7   € à—k‘k×'Ñ'×3Ñ3ò 	ˆFØ�{‰{˜dÓ"Ø’ð	ð r6   c                 ó‚   — d}| j                  |«      €|S | j                  «       D ]  }||j                  v sŒ|dz  }Œ |S )z(Get the number of shares of initializer.r   r   )rž   r�   r[   )r1   r\   Únumr,   s       r4   Úget_initializer_share_numz#ONNXModel.get_initializer_share_numî   sN   € àˆØ×Ñ Ó%Ð-ØˆJà—J‘J“Lò 	ˆDØ�t—z‘zÒ!Ø�q‘‘ð	ð ˆ
r6   c                 ót   — | j                   j                  j                  D ]  }|j                  |k(  sŒ|c S  y)zGet a node by name.N)r   r+   r,   r\   )r1   r\   r,   s      r4   Úget_nodezONNXModel.get_nodeù   s7   € à—K‘K×%Ñ%×*Ñ*ò 	ˆDØ�y‰y˜DÓ Ø’ð	ð r6   c                 ó¨   — || j                   j                  j                  v r0| j                   j                  j                  j                  |«       yy)z!Remove an initializer from model.N)r   r+   rƒ   rŠ   r—   s     r4   Úremove_initializerzONNXModel.remove_initializer   s=   € à�T—[‘[×&Ñ&×2Ñ2Ñ2Ø�K‰K×Ñ×)Ñ)×0Ñ0°Õ8ð 3r6   c                 ó4   — |D ]  }| j                  |«       Œ y)zRemove initializers from model.N)r¥   )r1   Úinit_to_removerƒ   s      r4   Úremove_initializerszONNXModel.remove_initializers  s   € à)ò 	1ˆKØ×#Ñ# KÕ0ñ	1r6   c                 ó~  — | j                  |«      }| j                  |«       |j                  }|j                  }|s>t        j
                  j                  ||||j                  «       j                  «       «      n1t        j
                  j                  ||||j                  «       |¬«      }| j                  |«       y)zUpdate initializer.)ÚrawN)rž   r¥   ÚdimsÚ	data_typer   ÚhelperÚmake_tensorÚflattenÚtolistÚtostringr™   )r1   r˜   Úarrayrª   Ú
old_tensorr«   r¬   Ú
new_tensors           r4   Úset_initializerzONNXModel.set_initializer
  sœ   € à×)Ñ)¨&Ó1ˆ
Ø×Ñ 
Ô+Ø�‰ˆØ×(Ñ(ˆ	ñ ô �K‰K×#Ñ# F¨I°t¸U¿]¹]»_×=SÑ=SÓ=UÔVä—‘×(Ñ(¨°¸DÀ%Ç.Á.ÓBRÐX[Ð(Ó\ð 	ð
 	×Ñ˜ZÕ(r6   c                 ó   — | j                   S )zReturn input names of nodes.)r)   rG   s    r4   Úinput_name_to_nodeszONNXModel.input_name_to_nodes  ó   € ð ×(Ñ(Ð(r6   c                 ó8  — |D �]  }|j                   D �cg c]R  }|j                  t        j                  j                  k(  s'|j                  t        j                  j
                  k(  r|‘ŒT }}t        |«      dkD  r,|D ]'  }| j                  |j                  j                  «       Œ) |j                  D ]\  }t        |j                  «       «      dk7  sŒ || j                  vr|g| j                  |<   Œ?| j                  |   j                  |«       Œ^ �Œ yc c}w )zGet input names of nodes.r   N)Ú	attributeÚtyper   ÚAttributeProtoÚGRAPHÚGRAPHSÚlenr*   Úgr,   r[   Ústripr)   Úappend)r1   r�   r,   ÚattrÚattrsÚ
input_names         r4   r*   z"ONNXModel._get_input_name_to_nodes  s   € àó 	KˆDð !ŸN™NöàØ—9‘9¤× 3Ñ 3× 9Ñ 9Ò9¸T¿Y¹YÌ$×J]ÑJ]×JdÑJdÒ=dò ðˆEð ô
 �5‹z˜AŠ~Ø!ò ?�DØ×1Ñ1°$·&±&·+±+Õ>ð?à"Ÿj™jò K�
Ü�z×'Ñ'Ó)Ó*¨aÓ/Ø!¨×)BÑ)BÑBØAEÀ˜×1Ñ1°*Ò=à×1Ñ1°*Ñ=×DÑDÀTÕJòKñ	Kùòs   •ADc                 ó   — | j                   S )zReturn output names of nodes.)r(   rG   s    r4   Úoutput_name_to_nodezONNXModel.output_name_to_node.  r¸   r6   c                 óØ  — |D ]à  }|j                   D �cg c]R  }|j                  t        j                  j                  k(  s'|j                  t        j                  j
                  k(  r|‘ŒT }}t        |«      dkD  r,|D ]'  }| j                  |j                  j                  «       Œ) |j                  D ].  }t        |j                  «       «      dk7  sŒ || j                  |<   Œ0 Œâ yc c}w )zGet output names of nodes.r   N)rº   r»   r   r¼   r½   r¾   r¿   r-   rÀ   r,   ra   rÁ   r(   )r1   r�   r,   rÃ   rÄ   Úoutput_names         r4   r-   z"ONNXModel._get_output_name_to_node3  s×   € àò 	BˆDð !ŸN™NöàØ—9‘9¤× 3Ñ 3× 9Ñ 9Ò9¸T¿Y¹YÌ$×J]ÑJ]×JdÑJdÒ=dò ðˆEð ô
 �5‹z˜AŠ~Ø!ò ?�DØ×1Ñ1°$·&±&·+±+Õ>ð?à#Ÿ{™{ò B�Ü�{×(Ñ(Ó*Ó+¨qÓ0Ø=A�D×-Ñ-¨kÒ:ñBñ	Bùòs   ”AC'c                 ó¸   — g }| j                  |«      D ]C  }| j                  |«      D ]-  }|j                  |j                  k7  sŒ|j                  |«       Œ/ ŒE |S )zGet siblings nodes.)Úget_parentsÚget_childrenr\   rÂ   )r1   r,   Úsiblingsr"   Úchilds        r4   Úget_siblingszONNXModel.get_siblingsB  s^   € àˆØ×&Ñ& tÓ,ò 	+ˆFØ×*Ñ*¨6Ó2ò +�Ø—:‘: §¡Ó*Ø—O‘O EÕ*ñ+ð	+ð ˆr6   Nc                 óˆ   — |€| j                   }g }|j                  D ]"  }||v sŒ||   D ]  }|j                  |«       Œ Œ$ |S )zGet children nodes.)r)   ra   rÂ   )r1   r,   r·   Úchildrenra   rÎ   s         r4   rÌ   zONNXModel.get_childrenK  s\   € àÐ&Ø"&×";Ñ";ÐàˆØ—k‘kò 	+ˆFØÐ,Ò,Ø0°Ñ8ò +�EØ—O‘O EÕ*ñ+ð	+ð ˆr6   c                 óz   — |€| j                   }g }|j                  D ]  }||v sŒ|j                  ||   «       Œ |S )zGet parents nodes.)r(   r[   rÂ   )r1   r,   rÇ   Úparentsr[   s        r4   rË   zONNXModel.get_parentsW  sN   € àÐ&Ø"&×";Ñ";ÐàˆØ—Z‘Zò 	;ˆEØÐ+Ò+Ø—‘Ð2°5Ñ9Õ:ð	;ð ˆr6   c                 ó‚   — |€| j                   }t        |j                  «      |k  ry|j                  |   }||vry||   S )zGet parent node by idx.N)r(   r¿   r[   )r1   r,   ÚidxrÇ   r[   s        r4   Ú
get_parentzONNXModel.get_parentb  sK   € àÐ&Ø"&×";Ñ";Ðäˆt�z‰z‹?˜cÒ!Øà—
‘
˜3‘ˆØÐ+Ñ+Øà" 5Ñ)Ð)r6   c                 ój   — t        |j                  «      }|j                  |«       t        ||«      }|S )zFind out node by name.)Úlistr,   r‘   r   )r1   Ú	node_nameÚnew_nodes_listr+   Úgraph_nodes_listr,   s         r4   Úfind_node_by_namezONNXModel.find_node_by_namep  s1   € ä §
¡
Ó+ÐØ×Ñ Ô/Ü˜IÐ'7Ó8ˆØˆr6   c                 ó�   — g }|j                   D ]4  }|j                  D ]#  }||j                  k(  sŒ|j                  |«       Œ% Œ6 |S )z2Find all nodes with given initializer as an input.)r,   r[   r\   rÂ   )r1   r+   rƒ   r�   r,   Ú
node_inputs         r4   Úfind_nodes_by_initializerz#ONNXModel.find_nodes_by_initializerw  sN   € àˆØ—J‘Jò 	'ˆDØ"Ÿj™jò '�
Ø ×!1Ñ!1Ó1Ø—L‘L Õ&ñ'ð	'ð ˆr6   c                 ó`  ‡ ‡— |j                  d«      st        j                  d|› d�«       yˆˆ fd„Š‰ j                  |   d   }|j                  dk(  r||j
                  d   k(  s!|j                  d	k(  r||j
                  d
   k(  ry ‰|«      \  }}|s
J d|› �«       ‚|s
J d|› �«       ‚||fS )z*Help function to get scale and zero_point.Ú
_quantizedzFind z) in the quantized graph is not quantized.©NNc                 ó¤  •— ‰
j                   |    d   }‰
j                  j                  | d«      }g d¢}|�N|j                  |v r@|j                  d   j                  dd«      j                  dd«      j                  dd«      }n€|j                  dv r@|j                  d   j                  dd«      j                  dd«      j                  dd«      }n2| j                  dd«      j                  dd«      j                  dd«      }|d	z   }‰
j                  |«      }|d
z   }‰
j                  |«      }|�|€|� ‰	|j                  d   «      \  }}||fS )z/Search scale and zero point tensor recursively.r   N)ÚReshapeÚ	TransposeÚSqueezeÚ	UnsqueezeÚMaxPoolÚPadÚSplitrá   rj   Ú_QuantizeLinearÚ_QuantizeInput)ÚGatherÚ_scaleÚ_zero_point)r)   r(   r   rg   r[   Úreplacera   rž   )Útensor_namer,   r"   Údirect_int8Úfp32_tensor_nameÚscaleÚscale_tensorÚzoÚ	zo_tensorÚ	_searcherr1   s            €€r4   rø   z+ONNXModel.get_scale_zero.<locals>._searcher†  s^  ø€ à×,Ñ,¨[Ñ9¸!Ñ<ˆDØ×.Ñ.×2Ñ2°;ÀÓEˆFÚeˆKØÐ! f§n¡n¸Ñ&Cà—L‘L ‘Oß‘W˜\¨2Ó.ß‘WÐ.°Ó3ß‘WÐ-¨rÓ2ñ	 !ð —‘ Ñ+à—K‘K ‘Nß‘W˜\¨2Ó.ß‘WÐ.°Ó3ß‘WÐ-¨rÓ2ñ	 !ð  ×'Ñ'¨°bÓ9×AÑAÐBSÐUWÓX×`Ñ`ÐaqÐsuÓvð !ð % xÑ/ˆEØ×/Ñ/°Ó6ˆLØ! MÑ1ˆBØ×,Ñ,¨RÓ0ˆIàÐ# yÐ'8ØÐ%Ù.7¸¿¹ÀQ¹Ó.HÑ+�L )Ø Ð*Ð*r6   r   ÚQLinearConvrl   ÚQGemméýÿÿÿzmissing scale for tensor zmissing zero point for tensor )Úendswithr   Údebugr)   rg   r[   )r1   r˜   r,   rõ   r÷   rø   s   `    @r4   Úget_scale_zerozONNXModel.get_scale_zero€  sÄ   ù€ à�‰˜|Ô,Ü�L‰L˜5  Ð(QÐRÔSØõ	+ðB ×(Ñ(¨Ñ0°Ñ3ˆð �L‰L˜MÒ)¨f¸¿
¹
À2¹Ò.FØ�L‰L˜GÒ#¨°$·*±*¸R±.Ò(@àá&/°Ó&7Ñ#ˆL˜)ÙÐEÐ#<¸V¸HÐ!EÓE�<ÙÐGÐ >¸v¸hÐGÓG�9Ø Ð*Ð*r6   c                 óÌ   — |rBt         j                  j                  | j                  dt	        |«      j
                  dz   ¬«       t        j                  | j                  |«       y)zBSave model to external data, which is needed for model size > 2GB.Tz.data)rq   rr   N)r   r   Úconvert_model_to_external_datar   r   r\   ry   )r1   Úoutput_pathÚuse_external_data_formats      r4   Úsave_model_to_filezONNXModel.save_model_to_file´  sO   € á#Ü×%Ñ%×DÑDØ—‘°TÄDÈÓDU×DZÑDZÐ]dÑDdð Eô ô 	�‰˜Ÿ™ [Õ1r6   c                 óÒ   — t        |t        «      rt        |t        «      sJ ‚t        t        | j                  «      «      D ]$  }| j                  |   |k(  sŒ|| j                  |<   Œ& y)zReplace input of a node.N)r   r   Úranger¿   r[   )r,   Úold_input_nameÚnew_input_nameÚjs       r4   Úreplace_node_inputzONNXModel.replace_node_input¼  sV   € ô ˜.¬#Ô.´:¸nÌcÔ3RÐRÐRÜ”s˜4Ÿ:™:“Ó'ò 	/ˆAØ�z‰z˜!‰} Ó.Ø .�—
‘
˜1’ñ	/r6   c                 ó^  — |€g }|€g }t        |«      dkD  rL| j                  j                  j                  D ](  }|j                  |v sŒt
        j                  |||«       Œ* y| j                  j                  j                  D ](  }|j                  |vsŒt
        j                  |||«       Œ* y)zReplace inputs of all nodes.Nr   )r¿   r2   r+   r,   rg   r
   r	  )r1   r  r  Úwhite_optypeÚblack_optyper,   s         r4   Úreplace_input_of_all_nodesz$ONNXModel.replace_input_of_all_nodesÄ  s¥   € àÐØˆLØÐØˆLÜˆ|Ó˜qÒ ØŸ
™
×(Ñ(×-Ñ-ò W�Ø—<‘< <Ò/Ü×0Ñ0°°~À~ÕVñWð Ÿ
™
×(Ñ(×-Ñ-ò W�Ø—<‘< |Ò3Ü×0Ñ0°°~À~ÕVñWr6   c                 óÒ   — t        |t        «      rt        |t        «      sJ ‚t        t        | j                  «      «      D ]$  }| j                  |   |k(  sŒ|| j                  |<   Œ& y)zReplace output of a node.N)r   r   r  r¿   ra   )r,   Úold_output_nameÚnew_output_namer  s       r4   Úreplace_node_outputzONNXModel.replace_node_outputÓ  sX   € ô ˜/¬3Ô/´J¸ÔPSÔ4TÐTÐTÜ”s˜4Ÿ;™;Ó'Ó(ò 	1ˆAØ�{‰{˜1‰~ Ó0Ø!0�—‘˜A’ñ	1r6   c                 ó^  — |€g }|€g }t        |«      dkD  rL| j                  j                  j                  D ](  }|j                  |v sŒt
        j                  |||«       Œ* y| j                  j                  j                  D ](  }|j                  |vsŒt
        j                  |||«       Œ* y)zReplace outputs of all nodes.Nr   )r¿   r2   r+   r,   rg   r
   r  )r1   r  r  r  r  r,   s         r4   Úreplace_output_of_all_nodesz%ONNXModel.replace_output_of_all_nodesÛ  s¥   € àÐØˆLØÐØˆLÜˆ|Ó˜qÒ ØŸ
™
×(Ñ(×-Ñ-ò Z�Ø—<‘< <Ò/Ü×1Ñ1°$¸ÈÕYñZð Ÿ
™
×(Ñ(×-Ñ-ò Z�Ø—<‘< |Ò3Ü×1Ñ1°$¸ÈÕYñZr6   c                 óê  — g }| j                  «       }|D �]É  }|j                  dk(  r\|j                  d   | j                  j                  j                  vr-|j                  d   | j
                  vr|j                  |«       Œo|j                  dk(  r¹t        | j                  |«      «      dk(  rœ| j                  |«      d   j                  dk(  r{|j                  d   | j                  vr`| j                  |«      d   j                  d   | j
                  vr3|j                  |«       |j                  | j                  |«      «       �Œ7d}|j                  D ]&  }|| j
                  v s|| j                  «       v sŒ$d} n |j                  D ]8  }| j                  |«      �Œ|| j                  v s|| j                  «       v sŒ6d} n |s�Œ¹|j                  |«       �ŒÌ | j                  |«       g }| j                  j                  j                  D ]»  }|j                  | j
                  vsŒ|j                  | j                  j                  j                  vsŒI|j                  |«       | j	                  «       j                  D ]E  }	|	j                  |j                  k(  sŒ| j	                  «       j                  j!                  |	«       ŒG Œ½ | j#                  |«       | j%                  «        y)	zRemove unused nodes.ÚConstantr   ÚQuantizeLinearr   ÚDequantizeLinearTFN)r�   rg   ra   r   r+   r)   rÂ   r¿   rÌ   r[   r(   r‘   rž   rŽ   rƒ   r\   rŠ   r¨   rc   )
r1   Úunused_nodesr�   r,   Úunusedra   r[   Úununsed_weightsÚwÚgraph_inputs
             r4   Úremove_unused_nodeszONNXModel.remove_unused_nodesê  s†  € àˆØ—
‘
“ˆØó 	.ˆDà—‘ 
Ò*Ø—K‘K ‘N¨$¯+©+×*;Ñ*;×*BÑ*BÑBØ—K‘K ‘N¨$×*CÑ*CÑCà×#Ñ# DÕ)à—‘Ð 0Ò0Ü˜×)Ñ)¨$Ó/Ó0°AÒ5Ø×%Ñ% dÓ+¨AÑ.×6Ñ6Ð:LÒLØ—J‘J˜q‘M¨×)BÑ)BÑBØ×%Ñ% dÓ+¨AÑ.×5Ñ5°aÑ8À×@YÑ@YÑYà×#Ñ# DÔ)Ø×#Ñ# D×$5Ñ$5°dÓ$;Ö<ð �Ø"Ÿk™kò �FØ ×!:Ñ!:Ñ:¸fÈÏÉËÒ>UØ!&˜Ùðð "ŸZ™Zò �EØ×+Ñ+¨EÓ2Ð>Ø Ø $×";Ñ";Ñ;¸uÈÏ
É
ËÒ?TØ!&˜Ùðó Ø ×'Ñ'¨Ö-ð=	.ð> 	×Ñ˜,Ô'àˆØ—‘×"Ñ"×.Ñ.ò 	?ˆAØ�v‰v˜T×6Ñ6Ò6¸1¿6¹6ÈÏÉ×IZÑIZ×IaÑIaÒ;aØ×&Ñ& qÔ)à#'§:¡:£<×#5Ñ#5ò ?�KØ"×'Ñ'¨1¯6©6Ó1ØŸ
™
›×*Ñ*×1Ñ1°+Õ>ñ?ð		?ð 	× Ñ  Ô1Ø�‰�r6   c           	      ó¾  ‡ ‡‡— |sªi }i Š‰ j                   j                  j                  D ]‚  }|j                  D ]>  }t	        |j                  «       «      dk7  sŒ ||vr|g||<   Œ+||   j                  |«       Œ@ |j                  D ]$  }t	        |j                  «       «      dk7  sŒ |‰|<   Œ& Œ„ n‰ j                  }‰ j                  Ši Št        «       }t        «       }‰ j                   j                  j                  D ]   }|j                  ||j                     «       Œ" ‰ j                   j                  j                  D ]3  }	t        ˆˆ fd„|	j                  D «       «      sŒ#|j                  |	«       Œ5 |rä|j                  «       }	t        ˆˆfd„|	j                  D «       «      s|	|vr|j                  |	«       ŒG|	‰|	j                  <   |	j                  D ]=  }
|
|v sŒ|j                  ||
   D �cg c]  }|j                  ‰vsŒ||vsŒ|‘Œ c}«       Œ? t	        |«      dk(  r3t	        |«      dk7  r%t        j                   |«      }|j#                  «        |rŒä‰j%                  «       D �cg c]  }|d   ‘Œ	 }}t	        t'        |D �	ch c]  }	|	j                  ’Œ c}	«      «      t	        t'        ‰ j                   j                  j                  D �	ch c]  }	|	j                  ’Œ c}	«      «      k(  sJ ‚‰ j                   j                  j)                  d«       ‰ j                   j                  j                  j                  |«       yc c}w c c}w c c}	w c c}	w )zTopological sort the model.r   c              3   óN   •K  — | ]  }|‰vxr |‰j                  «       v–— Œ y ­wr9   )r[   )r<   r^   rÇ   r1   s     €€r4   r>   z-ONNXModel.topological_sort.<locals>.<genexpr>5  s*   øè ø€ Ò[Èa�1Ð/Ð/ÒI°A¸T¿Z¹Z»\Ð4IÓIÑ[ùs   ƒ"%c              3   óJ   •K  — | ]  }|‰v sŒ‰|   j                   ‰v –— Œ y ­wr9   )r\   )r<   r^   Ú	all_nodesrÇ   s     €€r4   r>   z-ONNXModel.topological_sort.<locals>.<genexpr>:  s+   øè ø€ ÒmÀAÐTUÐYlÒTlÐ*¨1Ñ-×2Ñ2°iÔ?Ñmùs   ƒ	#�#r   r,   N)r2   r+   r,   r[   r¿   rÁ   rÂ   ra   r)   r(   r   r‘   r\   ÚallÚpopleftÚcopyÚdeepcopyÚclearÚitemsrØ   Ú
ClearField)r1   Úenable_subgraphr·   r,   rÅ   rÉ   ÚqÚwaitÚinpÚnÚoutr^   r�   r!  rÇ   s   `            @@r4   Útopological_sortzONNXModel.topological_sort  sá  ú€ ñ Ø"$ÐØ"$ÐØŸ
™
×(Ñ(×-Ñ-ò 	@�Ø"&§*¡*ò I�JÜ˜:×+Ñ+Ó-Ó.°!Ó3Ø%Ð-@Ñ@Ø?C¸fÐ/°
Ò;à/°
Ñ;×BÑBÀ4ÕHðIð $(§;¡;ò @�KÜ˜;×,Ñ,Ó.Ó/°1Ó4Ø;?Ð+¨KÒ8ñ@ñ	@ð #'×";Ñ";ÐØ"&×";Ñ";Ðàˆ	Ü‹GˆÜ‹wˆØ—:‘:×#Ñ#×)Ñ)ò 	4ˆCØ�H‰HÐ(¨¯©Ñ2Õ3ð	4à—‘×!Ñ!×&Ñ&ò 	ˆAÜÔ[ÐST×SZÑSZÔ[Õ[Ø—‘˜•ð	ñ Ø—	‘	“ˆAÜÔmÈÏÉÔmÔmØ˜D‘=Ø—K‘K ”NØà !ˆI�a—f‘fÑØ—x‘xò n�ØÐ-Ò-Ø—H‘HÐ)<¸SÑ)AÖl AÀQÇVÁVÐS\ÒE\ÐabÐjkÒakšaÒlÕmðnô �1‹v˜Š{œs 4›y¨Aš~Ü—M‘M $Ó'�Ø—
‘
”ò ð  )Ÿ™Ó0Ö1˜!��1“Ð1ˆÐ1Ü”4¨Ö/ A˜Ÿ›Ò/Ó0Ó1´S¼ÈtÏzÉz×O_ÑO_×OdÑOdÖ>eÈ!¸q¿v»vÒ>eÓ9fÓ5gÒgÐgÐgØ�
‰
×Ñ×#Ñ# FÔ+Ø�
‰
×Ñ×Ñ×$Ñ$ UÕ+ùò mùò 2ùÚ/ùÒ>es$   Ç3M
ÈM
ÈM
É/MÊMËMc                 óä  — |€g }t        «       }|D ]`  }t        |t        «      r|j                  |«       Œ%t        |t        j
                  «      r|j                  |j                  «       Œ[J d«       ‚ g }|D ]`  }t        |t        «      r|j                  |«       Œ%t        |t        j
                  «      r|j                  |j                  «       Œ[J d«       ‚ |r“|j                  «       }||v rŒ||vr|j                  |«       nŒ.t        |t        | j                  j                  j                  «      «      }| j                  |«      D ]  }|j                  |j                  «       Œ |rŒ“|S )z4Get nodes chain with given start node and stop node.zM'get_nodes_chain' function only support list[string]or list[NodeProto] params)r   r   r   rÂ   r   Ú	NodeProtor\   r#  r   rØ   r2   r+   r,   rË   )	r1   ÚstartÚstopÚresult_chainÚ
start_noder,   Ú	stop_noderÙ   r"   s	            r4   Úget_nodes_chainzONNXModel.get_nodes_chainK  sT  € àÐØˆLä“Wˆ
Øò 	nˆDÜ˜$¤Ô$Ø×!Ñ! $Õ'Ü˜D¤$§.¡.Ô1Ø×!Ñ! $§)¡)Õ,àmÐmÓm�uð	nð ˆ	Øò 	nˆDÜ˜$¤Ô$Ø× Ñ  Õ&Ü˜D¤$§.¡.Ô1Ø× Ñ  §¡Õ+àmÐmÓm�uð	nñ Ø"×*Ñ*Ó,ˆIØ˜IÑ%ØØ Ñ,Ø×#Ñ# IÕ.àä 	¬4°·
±
×0@Ñ0@×0EÑ0EÓ+FÓGˆDØ×*Ñ*¨4Ó0ò /�Ø×!Ñ! &§+¡+Õ.ð/ò ð Ðr6   c                 ó˜  — g }| j                   j                  j                  D �]#  }d\  }}|j                  dk(  r0|}| j	                  |g d¢g d¢«      | j	                  |g d¢g d¢«      g}|j                  dk(  r«|}| j	                  |g d¢g d¢«      | j	                  |g d¢g d	¢«      | j	                  |g d
¢g d¢| j
                  g ¬«      | j	                  |g d¢g d¢«      | j	                  |g d¢g d¢«      | j	                  |g d¢g d¢«      | j	                  |g d¢g d¢«      g}|s�Œt        |«      s�Œ|j                  |«       �Œ& |S )z,Find split node for layer wise quantization.râ   ÚSkipLayerNormalization©ÚMatMulrä   rå   rä   r;  ©Nr   r   r   r   ©ÚAddr;  rä   rå   r;  ©r   r   r   r   r   r>  ©r   Nr   r   r   ©r   Nr   r   r   ©rä   ÚGemmrä   rä   rå   r;  ©Nr   r   r   r   r   ©rÇ   Úreturn_indice©r>  r;  rä   rå   rä   r;  ©r   Nr   r   r   r   ©r   Nr   r   r   r   )r;  ÚMulr;  rJ  ÚDivr>  )Nr   Nr   Nr   )r;  rJ  r;  ÚSimplifiedLayerNormalizationr>  )Nr   Nr   r   )r   r+   r,   rg   Úmatch_parent_pathrÇ   ÚanyrÂ   )r1   Ústart_nodesr,   r5  Úqkv_nodes_lists        r4   Ú+find_split_node_for_layer_wise_quantizationz5ONNXModel.find_split_node_for_layer_wise_quantizationr  s‚  € ð ˆØ—K‘K×%Ñ%×*Ñ*ó >	+ˆDØ)3Ñ&ˆJ˜Ø�|‰|Ð7Ò7Ø!�
à×*Ñ*Ø"ÚOÚ*óð
 ×*Ñ*Ø"ÚKÚ'óð"�ð �|‰|˜uÒ$Ø!�
ð ×*Ñ*Ø"ÚKÚ*óð
 ×*Ñ*Ø"Ò$WÒYkóð ×*Ñ*Ø"ÚXÚ-Ø,0×,DÑ,DØ&(ð +ó ð ×*Ñ*Ø"ÚVÚ-óð
 ×*Ñ*Ø"ÚVÚ-óð
 ×*Ñ*Ø"ÚHÚ3óð
 ×*Ñ*Ø"ÚZÚ-óðE'"�ñP ÙÜ�~Ô&ÙØ×Ñ˜zÖ*ð}>	+ð~ Ðr6   c                 óx  — g }| j                   j                  j                  D �]  }|j                  dk(  rj	                  |j
                  g«       Œ0d\  }}|j                  dk(  r0|}| j                  |g d¢g d¢«      | j                  |g d¢g d¢«      g}|j                  dk(  r|}| j                  |g d¢g d	¢«      | j                  |g d¢g d
¢«      | j                  |g d¢g d¢| j                  g ¬«      | j                  |g d¢g d¢«      | j                  |g d¢g d¢«      g}|s�Œt        |«      s�Œ|D �cg c]  }|€Œ|‘Œ	 c}d   }g }|j                  D ]8  }|| j                  vrŒ||d   j                  d   k(  rŒ(|j	                  |«       Œ: t        |«      dk7  r�Œ‚|d   }	| j                  }
|
|	   }|D �cg c]  }|j                  ‘Œ }}|j                  d«      dk(  s�ŒÇj	                  |D �cg c]  }|j                  dk(  sŒ|j
                  ‘Œ  c}«       |r�Œ |S  S c c}w c c}w c c}w )z½Find qkv MatMul in Attention.

        Args:
            find_all (bool, optional): find all qkv MatMul. Defaults to False

        Returns:
            qkv (list): qkv MatMul list
        Ú	Attentionrâ   r9  r:  r<  r=  r?  r>  r@  rA  rB  rD  rE  rG  rH  rI  rl   r   r   r;  é   )r   r+   r,   rg   rÂ   r\   rM  rÇ   rN  r[   ra   r¿   r·   Úcount)r1   Úfind_allÚqkvr,   r5  rP  Ú	qkv_nodesÚother_inputsr[   Ú
root_inputr·   rÑ   rÎ   Úchildren_typess                 r4   Úfind_qkv_in_attentionzONNXModel.find_qkv_in_attention¾  sj  € ð ˆØ—K‘K×%Ñ%×*Ñ*ó H	ˆDØ�|‰|˜{Ò*Ø—
‘
˜DŸI™I˜;Ô'ØØ)3Ñ&ˆJ˜Ø�|‰|Ð7Ò7Ø!�
à×*Ñ*Ø"ÚOÚ*óð
 ×*Ñ*Ø"ÚKÚ'óð"�ð �|‰|˜uÒ$Ø!�
ð ×*Ñ*Ø"ÚKÚ*óð
 ×*Ñ*Ø"Ò$WÒYkóð ×*Ñ*Ø"ÚXÚ-Ø,0×,DÑ,DØ&(ð +ó ð ×*Ñ*Ø"ÚVÚ-óð
 ×*Ñ*Ø"ÚVÚ-óð1"�ñ< ÙÜ�~Ô&ÙØ(6ÖJ ¸#¹/šÒJÈ2ÑNˆIØˆLØ#×)Ñ)ò +�Ø × 8Ñ 8Ñ8ØØ˜I a™L×/Ñ/°Ñ2Ò2ØØ×#Ñ# EÕ*ð+ô �<Ó  AÒ%ÙØ% a™ˆJØ"&×":Ñ":ÐØ*¨:Ñ6ˆHØ9AÖB°˜eŸm›mÐBˆNÐBØ×#Ñ# HÓ-°Ô2Ø—
‘
°HÖZ¨5ÀÇÁÐQYÓ@Y˜EŸJ›JÒZÔ[ÛØØˆ
ðSH	ðR ˆ
ùò% Kùò CùâZs   Ä:H-ÅH-Æ?H2Ç9H7
ÈH7
c                 ó>  — g }t        t        |«      «      D ]ƒ  }|t        |«      dz
  k7  r1||dz      }|dz
  dk\  sŒ%|j                  ||dz
     ||dz
     g«       ŒE||   }||z   dz
  t        |«      k  sŒ_|j                  |||z   dz
     |||z   dz
     g«       Œ… |S )a  Find MatMul in FFN.

        Args:
            attention_index (list): index of Attention
            attention_matmul_list (list): list of Attention and MatMul nodes
            block_len (int): block length

        Returns:
            list: list of MatMul in FFN
        r   é   r   )r  r¿   rÂ   )r1   Úattention_indexÚattention_matmul_listÚ	block_lenÚ
ffn_matmulrÕ   Úindexs          r4   Úfind_ffn_matmulzONNXModel.find_ffn_matmul  sÙ   € ð ˆ
Üœ˜_Ó-Ó.ò 
	ˆCØ”c˜/Ó*¨QÑ.Ò.Ø'¨¨a©Ñ0�Ø˜1‘9 “>Ø×%Ñ%Ð'<¸UÀQ¹YÑ'GÐI^Ð_dÐghÑ_hÑIiÐ&jÕkà'¨Ñ,�Ø˜9Ñ$ qÑ(¬3Ð/DÓ+EÓEØ×%Ñ%Ø.¨u°yÑ/@À1Ñ/DÑEÐG\Ð]bÐenÑ]nÐqrÑ]rÑGsÐtõð
	ð Ðr6   c                 ó   — ddl m} ddlm} t	        ||«      r– || j
                  | j                  «      \  }}}| j                  |«       | j                  |«       | j                  |«       | j                  «        | j                  «        | j                  «        | j                  |«       yt        j                  d«       t!        d«       y)zExport Qlinear to QDQ model.r   )ÚONNXQlinear2QDQConfig)Úonnx_qlinear_to_qdqzGUnsupported config for export, only ONNXQlinear2QDQConfig is supported!N)Úneural_compressor.configrf  Úneural_compressor.utils.exportrg  r   r   r)   r•   rŽ   rœ   rc   r  r/  rz   r   r   Úexit)r1   Ú	save_pathÚconfrf  rg  r•   rŽ   Úinitss           r4   ÚexportzONNXModel.export,  s™   € åBÝFä�dÐ1Ô2Ù-@ÀÇÁÈd×NgÑNgÓ-hÑ*ˆI�| UØ�N‰N˜9Ô%Ø×Ñ˜lÔ+Ø×!Ñ! %Ô(Ø�K‰KŒMØ×$Ñ$Ô&Ø×!Ñ!Ô#Ø�I‰I�iÕ ä�N‰NÐdÔeÜ��Gr6   c                 ó  — g }|D ]K  }|| j                  «       vsŒt        j                  j                  «       }||_        |j                  |«       ŒM | j                  j                  j                   j                  |«       y)z�Add the tensors to the model outputs to gets their values.

        Args:
            tensor_names: The names of tensors to be dumped.
        N)	ra   r   r­   ÚValueInfoProtor\   rÂ   r   r+   r‘   )r1   Útensor_namesÚadded_outputsr˜   Úadded_tensors        r4   Úadd_tensors_to_outputsz ONNXModel.add_tensors_to_outputs>  sn   € ð ˆØ"ò 	3ˆFØ˜TŸ[™[›]Ò*Ü#Ÿ{™{×9Ñ9Ó;�Ø$*�Ô!Ø×$Ñ$ \Õ2ð		3ð
 	�‰×Ñ× Ñ ×'Ñ'¨Õ6r6   c                 óF  — g }|D ]d  }|| j                  «       v sŒ|j                  | j                  j                  j                   | j                  «       j	                  |«         «       Œf |D ]1  }| j                  j                  j                   j                  |«       Œ3 y)z€Remove the tensors from the model outputs.

        Args:
            tensor_names: The names of tensors to be removed.
        N)ra   rÂ   r   r+   rc  rŠ   )r1   rq  Úremoved_outputsr˜   ra   s        r4   Úremove_tensors_from_outputsz%ONNXModel.remove_tensors_from_outputsL  sŒ   € ð ˆØ"ò 	^ˆFØ˜Ÿ™›Ò&Ø×&Ñ& t§{¡{×'8Ñ'8×'?Ñ'?ÀÇÁÃ×@SÑ@SÐTZÓ@[Ñ'\Õ]ð	^ð &ò 	4ˆFØ�K‰K×Ñ×$Ñ$×+Ñ+¨FÕ3ñ	4r6   c                 óŽ   — |€g }t        |j                  «      D ])  \  }}||v sŒ||   }|j                  |k(  sŒ ||vsŒ%||fc S  y)a  Find parent node based on constraints on op_type.

        Args:
            node (str): current node name.
            parent_op_type (str): constraint of parent node op_type.
            output_name_to_node (dict): dictionary with output name as key, and node as value.
            exclude (list): list of nodes that are excluded (not allowed to match as parent).

        Returns:
            parent: The matched parent node. None if not found.
            index: The input index of matched parent node. None if not found.
        râ   )Ú	enumerater[   rg   )r1   r,   Úparent_op_typerÇ   Úexcluder^   r[   r"   s           r4   Úmatch_first_parentzONNXModel.match_first_parentY  s_   € ð ˆ?ØˆGÜ! $§*¡*Ó-ò 	%‰HˆAˆuØÐ+Ò+Ø,¨UÑ3�Ø—>‘> ^Ó3¸ÀgÒ8MØ! 1˜9Ò$ð		%ð
 r6   c                 ó$  — |€J ‚|�|dk\  sJ ‚|€g }|€| j                   }|€,| j                  ||||«      \  }}|�|j                  |«       |S |t        |j                  «      k\  ry| j                  |||«      }|�|j                  |k(  r||vr|S y)a|  Find parent node based on constraints on op_type and index.

        Args:
            node (str): current node name.
            parent_op_type (str): constraint of parent node op_type.
            input_index (int or None): only check the parent given input index of current node.
            output_name_to_node (dict): dictionary with output name as key, and node as value.
            exclude (list): list of nodes that are excluded (not allowed to match as parent).
            return_indice (list): a list to append the input index when input_index is None.

        Returns:
            parent: The matched parent node.
        Nr   )r(   r|  rÂ   r¿   r[   rÖ   rg   )	r1   r,   rz  Úinput_indexrÇ   r{  rF  r"   rc  s	            r4   Úmatch_parentzONNXModel.match_parento  sÁ   € ð, ÐÐÐØÐ" k°QÒ&6Ð6Ð6Øˆ?ØˆGØÐ&Ø"&×";Ñ";ÐàÐØ ×3Ñ3°D¸.ÐJ]Ð_fÓg‰MˆF�EØÐ(Ø×$Ñ$ UÔ+ØˆMàœ#˜dŸj™j›/Ò)Øà—‘  {Ð4GÓHˆØÐ &§.¡.°NÒ"BÀvÐU\ÑG\ØˆMàr6   c           	      óä   — t        |«      t        |«      k(  sJ ‚|€| j                  }|}g }t        |«      D ]6  \  }}	| j                  ||	||   |g |¬«      }
|
€ y|j	                  |
«       |
}Œ8 |S )aÃ  Find a sequence of input edges based on constraints on parent op_type and index.

        Args:
            node (str): current node name.
            parent_op_types (str): constraint of parent node op_type of each input edge.
            parent_input_index (list): constraint of input index of each input edge.
                                       None means no constraint.
            output_name_to_node (dict): dictionary with output name as key, and node as value.
            return_indice (list): a list to append the input index when there is
                                  no constraint on input index of an edge.

        Returns:
            parents: a list of matched parent node.
        N)r{  rF  )r¿   r(   ry  r  rÂ   )r1   r,   Úparent_op_typesÚparent_input_indexrÇ   rF  Úcurrent_nodeÚmatched_parentsr^   rg   Úmatched_parents              r4   rM  zONNXModel.match_parent_path›  s£   € ô, Ð%Ó&¬#¨oÓ*>Ò>Ð>Ð>àÐ&Ø"&×";Ñ";ÐàˆØˆÜ# OÓ4ò 	*‰JˆAˆwØ!×.Ñ.ØØØ" 1Ñ%Ø#ØØ+ð /ó ˆNð Ð%Ùà×"Ñ" >Ô2Ø)‰Lð	*ð Ðr6   c                 ón   — | j                   j                  j                  D ]  }d|j                  v sŒ y y)z~Check the model is smooth quantized or not.

        Returns:
            bool: the model is smooth quantized or not.
        Ú_smooth_scaleTF)r2   r+   rƒ   r\   )r1   Úinits     r4   Úis_smoothquant_modelzONNXModel.is_smoothquant_modelÉ  s7   € ð —J‘J×$Ñ$×0Ñ0ò 	ˆDØ $§)¡)Ò+Ùð	ð r6   c                 ó&   — | j                  «       }|S )z-Find split nodes for layer-wise quantization.)rQ  )r1   Úsplit_nodess     r4   Úfind_split_nodeszONNXModel.find_split_nodesÔ  s   € à×FÑFÓHˆØÐr6   c                 ó&
  — t        j                  «       }|j                  | j                  «       |j                  j                  d«       t        j                  «       }|j                  | j                  «       |j                  j                  d«       d}d}| j                  j                  j                  D ]u  }	|dk(  r&|j                  j                  j                  |	«       n*|dk(  r%|j                  j                  j                  |	«       |	j                  |k(  sŒh|	j                  }d}Œw t        |«      dk(  sJ d|› dt        |«      › d�«       ‚|d   }
|rH	 dd	lm}  || j                  d
t        j                  j                  | j                   «      ¬«      | _        | j)                  |
«      \  }}t         j*                  j-                  |
||«      }t/        |d
¬«      }t/        |d
¬«      }|j1                  «        |j1                  «        |j2                  j                  j                  j                  |«       |j2                  j                  j4                  j                  |«       g }g }|j6                  D ]­  }||j8                  v sŒ| j)                  |«      \  }}t         j*                  j-                  |||«      }||j2                  j                  j                  vr|j                  |«       ||j2                  j                  j4                  vsŒ�|j                  |«       Œ¯ |D ]1  }|j2                  j                  j                  j                  |«       Œ3 |D ]1  }|j2                  j                  j4                  j                  |«       Œ3 |j;                  «        |j;                  «        |j=                  «        |j=                  «        t        j                  j                  |«      }|j?                  |«       t        j                  jA                  |d«      }||_!        |jE                  |«       |jG                  «        t$        jI                  d|› d�«       |rv|j?                  |«       t        j                  jA                  |d«      }||_!        |jE                  |«       |jG                  «        t$        jI                  d|› d�«       ||fS ||fS # t"        $ r}t$        j'                  d«       |‚d}~ww xY w)a[  Split model into two parts at a given node.

        Args:
            split_node_name (str): name of the node where the model is split at>
            path_of_model_to_split (str): path of model to be split.
            shape_infer (bool): do shape inference. Default is True.
            save_both_split_models (bool): whether to save the two split models.
                False means only save the first split model.
                True means save both the two split models.
                Default id True.

        Returns:
            tuple: the first split model, the second split model
        r,   Nr   r^  zJOnly support split at node with 1 output tensor, while current split node z has z output tensorsr   )Úinfer_shapesT)Ú
auto_mergeÚbase_dirzËShape infer fails for layer-wise quantization. We would recommend checking the graph optimization level of your model and setting it to 'DISABLE_ALL' or 'ENABLE_BASIC', as this may help avoid this error.)r   zsplit_model_part_1.onnxzsave split model part 1 to z for layer wise quantizationzsplit_model_part_2.onnxzsave split model part 2 to )%r   Ú
ModelProtoÚCopyFromr   r+   r(  r,   rÂ   r\   ra   r¿   Ú'neural_compressor.adaptor.ox_utils.utilrŽ  r   r   r   r   Ú	Exceptionr   ÚerrorÚ%_get_output_type_shape_by_tensor_namer­   Úmake_tensor_value_infor
   Ú_remove_unused_input_outputr2   r[   rÇ   r·   Úremove_unused_initrc   Ú load_model_initializer_by_tensorÚjoinrK   Ú_save_split_modelr   rý   )r1   Úsplit_node_nameÚpath_of_model_to_splitÚshape_inferÚsave_both_split_modelsÚsplit_model_part_1Úsplit_model_part_2Úsplit_node_outputÚpart_idxr,   Úsplit_tensor_namerŽ  ÚeÚsplit_tensor_typeÚsplit_tensor_shapeÚsplit_tensorÚinsert_output_for_model_1Úinsert_input_for_model_2ra   Úoutput_typeÚoutput_shapeÚoutput_tensorr[   Údir_of_model_to_splitÚsplit_model_part_1_pathÚsplit_model_part_2_paths                             r4   Úsplit_model_with_nodezONNXModel.split_model_with_nodeÙ  sš  € ô* "Ÿ_™_Ó.ÐØ×#Ñ# D§K¡KÔ0Ø× Ñ ×+Ñ+¨FÔ3ä!Ÿ_™_Ó.ÐØ×#Ñ# D§K¡KÔ0Ø× Ñ ×+Ñ+¨FÔ3à ÐØˆØ—K‘K×%Ñ%×*Ñ*ò 	ˆDØ˜1Š}Ø"×(Ñ(×-Ñ-×4Ñ4°TÕ:Ø˜Q’Ø"×(Ñ(×-Ñ-×4Ñ4°TÔ:à�y‰y˜OÓ+Ø$(§K¡KÐ!Ø‘ð	ô Ð$Ó%¨Ò*ð 	
ØXÐYhÐXiÐinÔorð  tEó  pFð  oGð  GVð  Wó	
Ð*ð .¨aÑ0Ðñ ðÝPá*¨4¯;©;À4ÔRT×RYÑRY×RaÑRaÐbf×brÑbrÓRsÔt�”ð 15×0ZÑ0ZÐ[lÓ0mÑ-ÐÐ-Ü—{‘{×9Ñ9Ð:KÐM^Ð`rÓsˆä&Ð'9È$ÔOÐÜ&Ð'9È$ÔOÐð 	×6Ñ6Ô8Ø×6Ñ6Ô8à× Ñ ×&Ñ&×-Ñ-×4Ñ4°\ÔBØ× Ñ ×&Ñ&×,Ñ,×3Ñ3°LÔAà$&Ð!Ø#%Ð Ø(×<Ñ<ò 	CˆFØÐ+×?Ñ?Ò?Ø,0×,VÑ,VÐW]Ó,^Ñ)�˜\Ü $§¡× BÑ BÀ6È;ÐXdÓ e�Ø Ð(:×(@Ñ(@×(FÑ(F×(MÑ(MÑMØ-×4Ñ4°]ÔCØ Ð(:×(@Ñ(@×(FÑ(F×(LÑ(LÒLØ,×3Ñ3°MÕBð	Cð 0ò 	AˆFØ×$Ñ$×*Ñ*×1Ñ1×8Ñ8¸Õ@ð	Að .ò 	?ˆEØ×$Ñ$×*Ñ*×0Ñ0×7Ñ7¸Õ>ð	?ð 	×-Ñ-Ô/Ø×-Ñ-Ô/à×!Ñ!Ô#Ø×!Ñ!Ô#ä "§¡§¡Ð0FÓ GÐà×;Ñ;Ð<QÔRÜ"$§'¡'§,¡,Ð/DÐF_Ó"`ÐØ(?ÐÔ%Ø×,Ñ,Ð-DÔEØ×/Ñ/Ô1Ü�‰Ð2Ð3JÐ2KÐKgÐhÔiá!Ø×?Ñ?Ð@UÔVÜ&(§g¡g§l¡lÐ3HÐJcÓ&dÐ#Ø,CÐÔ)Ø×0Ñ0Ð1HÔIØ×3Ñ3Ô5Ü�L‰LÐ6Ð7NÐ6OÐOkÐlÔmØ%Ð'9Ð9Ð9à%Ð'9Ð9Ð9øôE ò Ü—‘ð9ôð �ûðús   ÅAS+ Ó+	TÓ4TÔTc           	      óî   — t         j                  j                  |dz   «      rt        j                  |dz   «       t	        j
                  | j                  |dd|j                  d«      d   dz   dd¬«       y)	z”Save split model as external data for layer wise quantization.

        Args:
            save_path (str): the path to save the split model
        rm   Trk   rl   rn   Fro   N)r   r   r!   rŠ   r   ry   r   rw   )r1   rk  s     r4   rœ  zONNXModel._save_split_modelQ  sb   € ô �7‰7�>‰>˜) gÑ-Ô.Ü�I‰I�i 'Ñ)Ô*Ü�‰Ø�K‰KØØ"&Ø$(Ø—_‘_ SÓ)¨"Ñ-°Ñ7ØØ#ö	
r6   c                 ó¦  — t         j                  j                  }d}| j                  j                  j
                  D ]Š  }|j                  |k(  sŒ|j                  j                  j                  }|j                  j                  j                  j                  D �cg c]!  }|j                  d«      r|j                  nd‘Œ# }} ||fS  ||fS c c}w )z°Get output type and shape with a tensor name.

        Args:
            tensor_name (str): name of a tensor

        Returns:
            tuple: output type and shape
        NÚ	dim_valuerl   )r   ÚTensorProtoÚFLOATr   r+   Ú
value_infor\   r»   Útensor_typeÚ	elem_typeÚshapeÚdimÚHasFieldrµ  )r1   rñ   rº  r»  ra   r¼  s         r4   r–  z/ONNXModel._get_output_type_shape_by_tensor_namec  sÂ   € ô ×$Ñ$×*Ñ*ˆ	ØˆØ—k‘k×'Ñ'×2Ñ2ò 	ˆFØ�{‰{˜kÓ)Ø"ŸK™K×3Ñ3×=Ñ=�	àRX×R]ÑR]×RiÑRi×RoÑRo×RsÑRsöØKN S§\¡\°+Ô%>�C—M’MÀBÑFð�ð ð Ø˜%ÐÐð	ð ˜%ÐÐùò	s   Â&Cc                 ó   — g }g }| j                   j                  j                  D ],  }|j                  | j                  vsŒ|j                  |«       Œ. | j                   j                  j                  D ],  }|j                  | j                  vsŒ|j                  |«       Œ. |D ]1  }| j                   j                  j                  j                  |«       Œ3 |D ]1  }| j                   j                  j                  j                  |«       Œ3 y)z-Remove unused input & output for split model.N)	r   r+   ra   r\   rÇ   rÂ   r[   r·   rŠ   )r1   Úremove_outputsÚremove_inputsra   r[   s        r4   r˜  z%ONNXModel._remove_unused_input_outputw  sè   € àˆØˆØ—k‘k×'Ñ'×.Ñ.ò 	.ˆFØ�{‰{ $×":Ñ":Ò:Ø×%Ñ% fÕ-ð	.ð —[‘[×&Ñ&×,Ñ,ò 	,ˆEØ�z‰z ×!9Ñ!9Ò9Ø×$Ñ$ UÕ+ð	,ð %ò 	4ˆFØ�K‰K×Ñ×$Ñ$×+Ñ+¨FÕ3ð	4à"ò 	2ˆEØ�K‰K×Ñ×#Ñ#×*Ñ*¨5Õ1ñ	2r6   c                 óÈ   — g }| j                   j                  j                  D ],  }|j                  | j                  vsŒ|j                  |«       Œ. | j                  |«       y)zRemove unused init.N)r   r+   rƒ   r\   r·   rÂ   r¨   )r1   Úremov_initsrˆ  s      r4   r™  zONNXModel.remove_unused_initˆ  sV   € àˆØ—K‘K×%Ñ%×1Ñ1ò 	)ˆDØ�y‰y × 8Ñ 8Ò8Ø×"Ñ" 4Õ(ð	)ð 	× Ñ  Õ-r6   c                 óX  — |€)t         j                  j                  | j                  «      }| j                  j
                  j                  D ]\  }|j                  d«      sŒ|j                  t        j                  j                  k(  sŒ=t        j                  j                  ||«       Œ^ y)z–Load model initializer by tensor.

        Args:
            data_path (str, optional): the directory of saved initializer. Defaults to None.
        NÚdata_location)r   r   r   r   r   r+   rƒ   r½  rÄ  r   r¶  ÚEXTERNALr   Úload_external_data_for_tensor)r1   Ú	data_pathrˆ  s      r4   rš  z*ONNXModel.load_model_initializer_by_tensor�  s~   € ð ÐÜŸ™Ÿ™¨×(8Ñ(8Ó9ˆIØ—K‘K×%Ñ%×1Ñ1ò 	YˆDØ�}‰}˜_Õ-°$×2DÑ2DÌ×HXÑHX×HaÑHaÓ2aÜ×)Ñ)×GÑGÈÈiÕXñ	Yr6   c                 óž  — |r¾t         j                  j                  t         j                  j                  t         j                  j	                  | j
                  «      |«      «      rZt        j                  t         j                  j                  t         j                  j	                  | j
                  «      |«      «       | j                  «        t        j                  j                  | j                  |¬«       t        j                  j                  | j                  t         j                  j	                  | j
                  «      ¬«       y)a}  Write external data of merged quantized model to new location to save memory.

        Args:
            external_data_location (str, optional): external data location of merged quantized model.
                                                    Defaults to "external.data".
            overwrite (bool, optional): if True, remove existed externa data. Defaults to False.
        )rr   )ÚfilepathN)r   r   r!   r›  r   r   rŠ   rš  r   r   r   r   Úwrite_external_data_tensors)r1   Úexternal_data_locationÚ	overwrites      r4   Ú#write_external_data_to_new_locationz-ONNXModel.write_external_data_to_new_locationœ  sÈ   € ñ œŸ™Ÿ™¬¯©¯©´R·W±W·_±_ÀT×EUÑEUÓ5VÐXnÓ(oÔpÜ�I‰I”b—g‘g—l‘l¤2§7¡7§?¡?°4×3CÑ3CÓ#DÐF\Ó]Ô^Ø×-Ñ-Ô/Ü×!Ñ!×@Ñ@ÀÇÁÐWmÐ@Ônä×!Ñ!×=Ñ=¸d¿k¹kÔTV×T[ÑT[×TcÑTcÐdh×dtÑdtÓTuÐ=Õvr6   c                 ó  — |j                  «        | j                  t        |j                  «       «      «       | j	                  t        |j                  «       «      «       | j                  «        |j                  «       j                  D ]N  }|j                  | j                  «       vsŒ | j                  j                  j                  j                  |«       ŒP g }| j                  j                  j                  D ]0  }|j                  |j                  «       v sŒ |j                  |«       Œ2 |D ]1  }| j                  j                  j                  j                  |«       Œ3 |j                  «       j                  D ]„  }|j                  | j                  «       vsŒ |j                  | j                  «       vsŒ=|j                  | j                  vsŒV| j                  j                  j                  j                  |«       Œ† y)z'Merge two split model into final model.N)rÍ  r•   rØ   r�   rœ   rƒ   rc   r+   ra   r\   r   rÂ   r[   rŠ   rÇ   )r1   Úto_merge_modelra   Úremove_outputr[   s        r4   Úmerge_split_modelszONNXModel.merge_split_models«  s‰  € à×:Ñ:Ô<Ø�‰”t˜N×0Ñ0Ó2Ó3Ô4Ø×Ñœd >×#=Ñ#=Ó#?Ó@ÔAØ�‰Œð %×*Ñ*Ó,×3Ñ3ò 	8ˆFØ�{‰{ $§+¡+£-Ò/Ø—‘×!Ñ!×(Ñ(×/Ñ/°Õ7ð	8ð
 ˆØ—k‘k×'Ñ'×.Ñ.ò 	-ˆFØ�{‰{˜n×2Ñ2Ó4Ò4Ø×$Ñ$ VÕ,ð	-ð $ò 	4ˆFØ�K‰K×Ñ×$Ñ$×+Ñ+¨FÕ3ð	4ð $×)Ñ)Ó+×1Ñ1ò 	6ˆEà—
‘
 $§*¡*£,Ò.Ø—J‘J d§k¡k£mÒ3Ø—J‘J d×&>Ñ&>Ò>à—‘×!Ñ!×'Ñ'×.Ñ.¨uÕ5ñ	6r6   c                 ót  — i }g }| j                   j                  j                  D ]"  }|||j                  <   |j	                  |«       Œ$ |D ]1  }| j                   j                  j                  j                  |«       Œ3 |D ]4  }| j                   j                  j                  j	                  ||   «       Œ6 y)z:Re-org output of merged model for layer-wise quantization.N)r   r+   ra   r\   rÂ   rŠ   )r1   Úorigin_outputÚoutputsÚ
tmp_removera   Úout_names         r4   Úre_org_outputzONNXModel.re_org_outputÈ  sª   € àˆØˆ
Ø—k‘k×'Ñ'×.Ñ.ò 	&ˆFØ#)ˆG�F—K‘KÑ Ø×Ñ˜fÕ%ð	&ð !ò 	4ˆFØ�K‰K×Ñ×$Ñ$×+Ñ+¨FÕ3ð	4ð &ò 	?ˆHØ�K‰K×Ñ×$Ñ$×+Ñ+¨G°HÑ,=Õ>ñ	?r6   )Fr9   râ   )NNNN)TT)zexternal.dataF)MÚ__name__Ú
__module__Ú__qualname__Ú__doc__r5   r   ÚpropertyrH   rK   ÚsetterrQ   rT   rW   r2   r[   ra   rc   re   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  Ústaticmethodr	  r  r  r  r  r/  r7  rQ  r\  rd  rn  rt  rw  r|  r  rM  r‰  rŒ  r²  rœ  r–  r˜  r™  rš  rÍ  rÑ  r×  rP   r6   r4   r
   r
   &   su  „ ÙòòBCð ñ$ó ð$ð ñ ó ð ð ×Ññ ó ð òð ñó ðð ‡_�_ñ"ó ð"ð ñó ðð ñó ðð ‡\�\ñ>ó ð>ò9ò:ò>ð ñ ó ð ò>ò
Jò0&ò-ò!ò&ò(ò0ò
#ò
.ò4ò;ò
)ò
ò	òò9ò
1ó
)ð ñ)ó ð)òKð$ ñ)ó ð)òBòó
ó	ó*òòò2+óh2ð ñ/ó ð/óWð ñ1ó ð1óZò/ób.,ó`%òNJóXSòjò2ò$7ò4óð4 Ø ØØó*ðb !Øó,ò\	òð aeóv:òp
ò$ ò(2ò".ó
Yówò6ó:?r6   r
   )rÛ  r$  Úloggingr   Úcollectionsr   Úpathlibr   r   Úonnx.external_data_helperÚonnx_irr?   Úutilr   r   Ú	getLoggerr   r
   rP   r6   r4   ú<module>ræ     sD   ðñ& ã Û Û 	Ý Ý ã Û  Û ç 0à	ˆ×	Ñ	Ð.Ó	/€÷
n?ò n?r6   