Ë
    �…jÞ
 ã                   óÈ   — 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	Z	 d dl
mZmZmZmZmZmZmZmZmZ d dlmZmZ d dlmZ  ej2                  e«      Z G d„ d	«      Zy)
é    N)Údeque)ÚPath)Úconvert_float_to_float16)	ÚAttributeProtoÚ
GraphProtoÚ
ModelProtoÚ	NodeProtoÚTensorProtoÚValueInfoProtoÚhelperÚnumpy_helperÚ
save_model)Úload_external_data_for_tensorÚuses_external_data)ÚSymbolicShapeInferenceHelperc                   óh  — e Zd Zd„ Zd„ Zd„ Zi dfd„Zdid„Zdid„Zd„ Z	d	„ Z
d
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdjd„Zdjd„Zdjd„Zdjd„Zed„ «       Zd„ Zed„ «       Zd„ Zd„ Zd„ Zdkd„Zdjd„Z djd „Z!g fd!„Z"ddg dfd"„Z#d#„ Z$d$„ Z%	 	 	 dld%„Z&dmd&„Z'ddg fd'e(e)e*e*f      dz  fd(„Z+dmd)„Z,d*„ Z-d+„ Z.dnd,„Z/d-„ Z0dnd.„Z1djd/„Z2d0„ Z3djd1e4d2e5dz  fd3„Z6djd1e4d2e5dz  fd4„Z7ed5e8d6e4fd7„«       Z9d8„ Z:d9„ Z;dod:„Z<dod;„Z=djd<„Z>d=„ Z?d>„ Z@djd?„ZAdid@„ZBedA„ «       ZCdB„ ZDdC„ ZEdD„ ZFdmdE„ZGdpdF„ZHdG„ ZIedidH„«       ZJdpdI„ZKe	 	 	 	 dqdJ„«       ZL	 	 	 	 dqdK„ZMdL„ ZNdM„ ZOdidN„ZPedrdOeQdPe4dQe*fdR„«       ZRe	 	 	 	 dsdSeQdTeQdUeSdz  dVeSdz  dWeTdXeTdQeUfdY„«       ZVdZ„ ZWd[eSdz  fd\„ZXd]e4fd^„ZYd_„ ZZd`„ Z[dae\dbe*fdc„Z]dde\dbe*fde„Z^dfe4dge4fdh„Z_y)tÚ	OnnxModelc                 ó&   — | j                  |«       y ©N)Ú
initialize©ÚselfÚmodels     úd/root/aria/tools/markitdown-venv/lib/python3.12/site-packages/onnxruntime/transformers/onnx_model.pyÚ__init__zOnnxModel.__init__    s   € Ø�‰˜Õó    c                 óf   — || _         i | _        d | _        d| _        d | _        d | _        d | _        y ©NT)r   Ú_node_name_suffixÚshape_infer_helperÚenable_shape_inferÚ
all_graphsÚ_dtype_dictÚ_shape_dictr   s     r   r   zOnnxModel.initialize#   s:   € Ø!&ˆŒ
Ø13ˆÔØ@DˆÔØ(,ˆÔØ37ˆŒð
 37ˆÔØ37ˆÕr   c                 ó   — d| _         y )NF)r!   ©r   s    r   Údisable_shape_inferencez!OnnxModel.disable_shape_inference0   s
   € Ø"'ˆÕr   Fc                 ó.  — | j                   rR| j                  �|rt        | j                  «      | _        	 | j                  j	                  |«      r| j                  S 	 y y # t
        $ r+ d| _         t        dt        j                  «       d   «       Y y w xY w)NFzfailed in shape inferencer   )	r!   r    r   r   ÚinferÚ	ExceptionÚprintÚsysÚexc_info)r   Údynamic_axis_mappingÚupdates      r   Úinfer_runtime_shapezOnnxModel.infer_runtime_shape3   s�   € Ø×"Ò"Ø×&Ñ&Ð.±&Ü*FÀtÇzÁzÓ*R�Ô'ðFØ×*Ñ*×0Ñ0Ð1EÔFØ×2Ñ2Ð2ð Gñ øô	 ò FØ*/�Ô'ÜÐ1´3·<±<³>À!Ñ3DÕEàð	Fús   ¶&A  Á 1BÂBc                 óâ   — i }|s| j                  «       n| j                  j                  j                  }|D ]5  }|j                  D ]$  }|sŒ||vr|g||<   Œ||   j                  |«       Œ& Œ7 |S r   )Únodesr   ÚgraphÚnodeÚinputÚappend)r   Úexclude_subgraphsÚinput_name_to_nodesÚnodes_to_searchr4   Ú
input_names         r   r8   zOnnxModel.input_name_to_nodesA   s�   € Ø ÐÙ.?˜$Ÿ*™*œ,ÀTÇZÁZ×EUÑEU×EZÑEZˆØ#ò 	EˆDØ"Ÿj™jò E�
ÚØ!Ð)<Ñ<Ø;?¸&Ð+¨JÒ7à+¨JÑ7×>Ñ>¸tÕDñEð	Eð #Ð"r   c                 ó®   — i }|s| j                  «       n| j                  j                  j                  }|D ]  }|j                  D ]
  }|sŒ|||<   Œ Œ |S r   )r2   r   r3   r4   Úoutput)r   r7   Úoutput_name_to_noder9   r4   Úoutput_names         r   r=   zOnnxModel.output_name_to_nodeM   s_   € Ø ÐÙ.?˜$Ÿ*™*œ,ÀTÇZÁZ×EUÑEU×EZÑEZˆØ#ò 	<ˆDØ#Ÿ{™{ò <�ÚØ7;Ð'¨Ò4ñ<ð	<ð #Ð"r   c                 óF   — t        | j                  j                  «      g}|S r   )Úlistr   Ú	functions)r   Úall_functionss     r   rA   zOnnxModel.functionsV   s   € Ü˜dŸj™j×2Ñ2Ó3Ð4ˆØÐr   c                 óx   — g }| j                  «       D ]$  }|j                  D ]  }|j                  |«       Œ Œ& |S r   )Úgraphsr4   r6   )r   Ú	all_nodesr3   r4   s       r   r2   zOnnxModel.nodesZ   sE   € Øˆ	Ø—[‘[“]ò 	'ˆEØŸ
™
ò '�Ø× Ñ  Õ&ñ'ð	'ð Ðr   c                 ó.   — | j                   j                  S r   )r   r3   r&   s    r   r3   zOnnxModel.grapha   s   € Ø�z‰z×ÑÐr   c                 ó¤  — | j                   �| j                   S g | _         | j                  j                  g}|�r|j                  d«      }| j                   j	                  |«       |j
                  D ]Í  }|j                  D ]¼  }|j                  t        j                  j                  k(  r7t        |j                  t        «      sJ ‚|j	                  |j                  «       |j                  t        j                  j                  k(  sŒ‰|j                  D ]%  }t        |t        «      sJ ‚|j	                  |«       Œ' Œ¾ ŒÏ |r�Œ| j                   S ©Nr   )r"   r   r3   Úpopr6   r4   Ú	attributeÚtyper   ÚAttributeTypeÚGRAPHÚ
isinstanceÚgr   ÚGRAPHSrD   )r   Úgraph_queuer3   r4   ÚattrrO   s         r   rD   zOnnxModel.graphsd   s  € Ø�?‰?Ð&Ø—?‘?Ð"ØˆŒØ—z‘z×'Ñ'Ð(ˆÚØ—O‘O AÓ&ˆEØ�O‰O×"Ñ" 5Ô)ØŸ
™
ò 2�Ø ŸN™Nò 2�DØ—y‘y¤N×$@Ñ$@×$FÑ$FÒFÜ)¨$¯&©&´*Ô=Ð=Ð=Ø#×*Ñ*¨4¯6©6Ô2Ø—y‘y¤N×$@Ñ$@×$GÑ$GÓGØ!%§¡ò 2˜AÜ#-¨a´Ô#<Ð<Ð#<Ø'×.Ñ.¨qÕ1ñ2ñ2ð2ó ð �‰Ðr   c                 óŒ   — g }| j                  «       D ].  }|j                  D ]  }|j                  |j                  «       Œ Œ0 |S r   )rD   r5   r6   Úname)r   Úinput_namesr3   r5   s       r   Úget_graphs_input_namesz OnnxModel.get_graphs_input_namesw   sI   € ØˆØ—[‘[“]ò 	/ˆEØŸ™ò /�Ø×"Ñ" 5§:¡:Õ.ñ/ð	/ð Ðr   c                 óŒ   — g }| j                  «       D ].  }|j                  D ]  }|j                  |j                  «       Œ Œ0 |S r   )rD   r<   r6   rT   )r   Úoutput_namesr3   r<   s       r   Úget_graphs_output_namesz!OnnxModel.get_graphs_output_names~   sI   € ØˆØ—[‘[“]ò 	1ˆEØŸ,™,ò 1�Ø×#Ñ# F§K¡KÕ0ñ1ð	1ð Ðr   c                 óR   — | j                  «       D ]  }||j                  v sŒ|c S  y r   )rD   r4   ©r   r4   r3   s      r   Úget_graph_by_nodezOnnxModel.get_graph_by_node…   s-   € Ø—[‘[“]ò 	ˆEØ�u—z‘zÒ!Ø’ð	ð r   c                 óT   — | j                  «       D ]  }||j                  k(  sŒ|c S  y r   )rD   rT   )r   Ú
graph_namer3   s      r   Úget_graph_by_namezOnnxModel.get_graph_by_name‹   s-   € Ø—[‘[“]ò 	ˆEØ˜UŸZ™ZÓ'Ø’ð	ð r   c                 óœ   — t        |j                  «      D ]   \  }}|j                  D ]  }||v sŒ|c c S  Œ" t        |j                  «      S r   )Ú	enumerater4   r5   Úlen)r   r3   ÚoutputsÚidxr4   r5   s         r   Úget_topological_insert_idz#OnnxModel.get_topological_insert_id‘   sN   € Ü" 5§:¡:Ó.ò 	‰IˆC�ØŸ™ò �Ø˜GÒ#Ø”Jñð	ô �5—:‘:‹Ðr   c                 ó°   — | j                  «       D ]-  }||j                  v sŒ|j                  j                  |«        y  t        j	                  d|«       y )NzFailed to remove node %s)rD   r4   ÚremoveÚloggerÚwarningr[   s      r   Úremove_nodezOnnxModel.remove_node˜   sI   € Ø—[‘[“]ò 	ˆEØ�u—z‘zÒ!Ø—
‘
×!Ñ! $Ô'Ùð	ô 	�‰Ð1°4Õ8r   c                 ó4   — |D ]  }| j                  |«       Œ y r   )rj   )r   Únodes_to_remover4   s      r   Úremove_nodeszOnnxModel.remove_nodesŸ   s   € Ø#ò 	#ˆDØ×Ñ˜TÕ"ñ	#r   Nc                 óB  — |�#|| j                   j                  j                  k(  r1| j                   j                  j                  j	                  |g«       y | j                  |«      }| j                  ||j                  «      }|j                  j                  ||«       y r   )	r   r3   rT   r4   Úextendr_   re   r<   Úinsert)r   r4   r^   r3   Ú
insert_idxs        r   Úadd_nodezOnnxModel.add_node£   sy   € ØÐ ¨t¯z©z×/?Ñ/?×/DÑ/DÒ!DØ�J‰J×Ñ×!Ñ!×(Ñ(¨$¨Õ0à×*Ñ*¨:Ó6ˆEØ×7Ñ7¸¸t¿{¹{ÓKˆJØ�J‰J×Ñ˜j¨$Õ/r   c                 ó¸   — |€0| j                   j                  j                  j                  |«       y |D ]#  }||j                     }| j                  ||«       Œ% y r   )r   r3   r4   ro   rT   rr   )r   Únodes_to_addÚnode_name_to_graph_namer4   r^   s        r   Ú	add_nodeszOnnxModel.add_nodes«   sQ   € Ø"Ð*Ø�J‰J×Ñ×!Ñ!×(Ñ(¨Õ6à$ò 0�Ø4°T·Y±YÑ?�
Ø—‘˜d JÕ/ñ0r   c                 ó
  — |�#|| j                   j                  j                  k(  r1| j                   j                  j                  j	                  |g«       y | j                  |«      }|j                  j	                  |g«       y r   )r   r3   rT   Úinitializerro   r_   )r   Útensorr^   r3   s       r   Úadd_initializerzOnnxModel.add_initializer³   se   € ØÐ ¨t¯z©z×/?Ñ/?×/DÑ/DÒ!DØ�J‰J×Ñ×(Ñ(×/Ñ/°°Õ9à×*Ñ*¨:Ó6ˆEØ×Ñ×$Ñ$ f XÕ.r   c                 ó
  — |�#|| j                   j                  j                  k(  r1| j                   j                  j                  j	                  |g«       y | j                  |«      }|j                  j	                  |g«       y r   )r   r3   rT   r5   ro   r_   )r   r5   r^   r3   s       r   Ú	add_inputzOnnxModel.add_inputº   sc   € ØÐ ¨t¯z©z×/?Ñ/?×/DÑ/DÒ!DØ�J‰J×Ñ×"Ñ"×)Ñ)¨5¨'Õ2à×*Ñ*¨:Ó6ˆEØ�K‰K×Ñ ˜wÕ'r   c                 óÒ   — t        |t        «      rt        |t        «      sJ ‚t        t        | j                  «      «      D ]$  }| j                  |   |k(  sŒ|| j                  |<   Œ& y r   )rN   ÚstrÚrangerb   r5   )r4   Úold_input_nameÚnew_input_nameÚjs       r   Úreplace_node_inputzOnnxModel.replace_node_inputÁ   sT   € ä˜.¬#Ô.´:¸nÌcÔ3RÐRÐRÜ”s˜4Ÿ:™:“Ó'ò 	/ˆAØ�z‰z˜!‰} Ó.Ø .�—
‘
˜1’ñ	/r   c                 ó\   — | j                  «       D ]  }t        j                  |||«       Œ y r   )r2   r   rƒ   )r   r€   r�   r4   s       r   Úreplace_input_of_all_nodesz$OnnxModel.replace_input_of_all_nodesÈ   s+   € Ø—J‘J“Lò 	OˆDÜ×(Ñ(¨¨~¸~ÕNñ	Or   c                 óÒ   — t        |t        «      rt        |t        «      sJ ‚t        t        | j                  «      «      D ]$  }| j                  |   |k(  sŒ|| j                  |<   Œ& y r   )rN   r~   r   rb   r<   )r4   Úold_output_nameÚnew_output_namer‚   s       r   Úreplace_node_outputzOnnxModel.replace_node_outputÌ   sV   € ä˜/¬3Ô/´J¸ÔPSÔ4TÐTÐTÜ”s˜4Ÿ;™;Ó'Ó(ò 	1ˆAØ�{‰{˜1‰~ Ó0Ø!0�—‘˜A’ñ	1r   c                 ó|   — | j                   j                  j                  D ]  }t        j	                  |||«       Œ y r   )r   r3   r4   r   r‰   )r   r‡   rˆ   r4   s       r   Úreplace_output_of_all_nodesz%OnnxModel.replace_output_of_all_nodesÓ   s7   € ð —J‘J×$Ñ$×)Ñ)ò 	RˆDÜ×)Ñ)¨$°ÀÕQñ	Rr   c                 óz   — | j                  «       D ](  }|j                  D ]  }|j                  |k(  sŒ|c c S  Œ* y r   )rD   rx   rT   )r   rT   r3   ry   s       r   Úget_initializerzOnnxModel.get_initializerÝ   sB   € Ø—[‘[“]ò 	"ˆEØ×+Ñ+ò "�Ø—;‘; $Ó&Ø!”Mñ"ð	"ð r   c                 óv   — g }| j                  «       D ]#  }|j                  |k(  sŒ|j                  |«       Œ% |S r   )r2   Úop_typer6   )r   r�   r2   r4   s       r   Úget_nodes_by_op_typezOnnxModel.get_nodes_by_op_typeä   s;   € ØˆØ—J‘J“Lò 	#ˆDØ�|‰|˜wÓ&Ø—‘˜TÕ"ð	#ð ˆr   c                 óü   — |€| j                  «       }g }|�;|t        |j                  «      k  r!|j                  |   }||v rt        ||   «      }|S |j                  D ]  }||v sŒ|j	                  ||   «       Œ |S r   )r8   rb   r<   r@   ro   )r   r4   r8   Úoutput_indexÚchildrenr<   s         r   Úget_childrenzOnnxModel.get_childrenë   sš   € ØÐ&Ø"&×":Ñ":Ó"<ÐàˆØÐ#Øœc $§+¡+Ó.Ò.ØŸ™ \Ñ2�ØÐ0Ñ0Ü#Ð$7¸Ñ$?Ó@�Hð ˆð	 Ÿ+™+ò A�ØÐ0Ò0Ø—O‘OÐ$7¸Ñ$?Õ@ðAð ˆr   c                 ó‚   — |€| j                  «       }g }|j                  D ]  }||v sŒ|j                  ||   «       Œ |S r   )r=   r5   r6   )r   r4   r=   Úparentsr5   s        r   Úget_parentszOnnxModel.get_parentsü   sQ   € ØÐ&Ø"&×":Ñ":Ó"<ÐàˆØ—Z‘Zò 	;ˆEØÐ+Ò+Ø—‘Ð2°5Ñ9Õ:ð	;ð ˆr   c                 óŠ   — |€| j                  «       }t        |j                  «      |k  ry |j                  |   }||vry ||   S r   )r=   rb   r5   )r   r4   Úir=   r5   s        r   Ú
get_parentzOnnxModel.get_parent  sN   € ØÐ&Ø"&×":Ñ":Ó"<Ðäˆt�z‰z‹?˜aÒØà—
‘
˜1‘ˆØÐ+Ñ+Øà" 5Ñ)Ð)r   c                 óÎ   — t        |j                  «      D ]M  \  }}||v sŒ||   }|j                  |k(  r
||vr||fc S t        j	                  d|› d|j                  › �«       ŒO 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.
        zTo find first z
, current ©NN)ra   r5   r�   rh   Údebug)r   r4   Úparent_op_typer=   Úexcluder™   r5   Úparents           r   Úmatch_first_parentzOnnxModel.match_first_parent  sv   € ô " $§*¡*Ó-ò 	^‰HˆAˆuØÐ+Ò+Ø,¨UÑ3�Ø—>‘> ^Ò3¸ÀgÑ8MØ! 1˜9Ò$ä—L‘L >°.Ð1AÀÈFÏNÉNÐK[Ð!\Õ]ð	^ð r   c                 óÎ  — |€J ‚|�|dk\  sJ ‚|€| j                  «       }|€,| j                  ||||«      \  }}|�|j                  |«       |S |t        |j                  «      k\  r/t
        j                  d|› dt        |j                  «      › �«       y| j                  |||«      }|�|j                  |k(  r||vr|S |�%t
        j                  d|› d|j                  › �«       y)a*  
        Find parent node based on constraints on op_type and index.
        When input_index is None, we will find the first parent node based on constraints,
        and return_indice will be appended the corresponding input 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   zinput_index z >= node inputs zExpect z, Got )	r=   r¡   r6   rb   r5   rh   r�   rš   r�   )	r   r4   rž   Úinput_indexr=   rŸ   Úreturn_indicer    Úindexs	            r   Úmatch_parentzOnnxModel.match_parent*  s  € ð2 ÐÐÐØÐ" k°QÒ&6Ð6Ð6àÐ&Ø"&×":Ñ":Ó"<ÐàÐØ ×3Ñ3°D¸.ÐJ]Ð_fÓg‰MˆF�EØÐ(Ø×$Ñ$ UÔ+ØˆMàœ#˜dŸj™j›/Ò)Ü�L‰L˜<¨ }Ð4DÄSÈÏÉÃ_ÐDUÐVÔWØà—‘  {Ð4GÓHˆØÐ &§.¡.°NÒ"BÀvÐU\ÑG\ØˆMàÐÜ�L‰L˜7 >Ð"2°&¸¿¹Ð8HÐIÔJàr   c                 ó¦   — t        |«      D ]C  \  }}t        |t        t        f«      sJ ‚g }| j	                  ||d   |d   ||«      }|sŒ>|||fc S  y)Nr   é   )éÿÿÿÿNN)ra   rN   r@   ÚtupleÚmatch_parent_path)r   r4   Úpathsr=   r™   Úpathr¤   Úmatcheds           r   Úmatch_parent_pathszOnnxModel.match_parent_paths\  sj   € Ü  Ó'ò 	1‰GˆAˆtÜ˜d¤T¬5 MÔ2Ð2Ð2ØˆMØ×,Ñ,¨T°4¸±7¸DÀ¹GÐEXÐZgÓhˆGÚØ˜' =Ð0Ò0ð	1ð r   c                 ó  — g g g }}}t        |«      D ]p  \  }}t        |t        t        f«      sJ ‚g }	| j	                  ||d   |d   ||	«      }
|
sŒ>|j                  |«       |j                  |
«       |j                  |	«       Œr |||fS )Nr   r¨   )ra   rN   r@   rª   r«   r6   )r   r4   r¬   r=   Úmatch_iÚmatchesÚreturn_indicesr™   r­   r¤   r®   s              r   Úmatch_parent_paths_allz OnnxModel.match_parent_paths_alle  sš   € Ø+-¨r°2˜.�ˆÜ  Ó'ò 	5‰GˆAˆtÜ˜d¤T¬5 MÔ2Ð2Ð2ØˆMØ×,Ñ,¨T°4¸±7¸DÀ¹GÐEXÐZgÓhˆGÚØ—‘˜qÔ!Ø—‘˜wÔ'Ø×%Ñ% mÕ4ð	5ð ˜ Ð/Ð/r   c           	      ó€  — |�t        |«      t        |«      k(  sJ ‚|€| j                  «       }|}g }t        |«      D ]~  \  }}	| j                  ||	|�||   nd|g |¬«      }
|
€F|�%t        j                  d|› d||   › d|	› �d¬«        yt        j                  d|› d|	› �d¬«        y|j                  |
«       |
}Œ€ |S )aJ  
        Find a sequence of input edges based on constraints on parent op_type and index.
        When input_index is None, we will find the first parent node based on constraints,
        and return_indice will be appended the corresponding input 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Ÿ   r¤   zFailed to match index=z parent_input_index=ú	 op_type=T©Ú
stack_info)rb   r=   ra   r¦   rh   r�   r6   )r   r4   Úparent_op_typesÚparent_input_indexr=   r¤   Úcurrent_nodeÚmatched_parentsr™   r�   Úmatched_parents              r   r«   zOnnxModel.match_parent_pathq  s  € ð0 Ð)ÜÐ)Ó*¬c°/Ó.BÒBÐBÐBàÐ&Ø"&×":Ñ":Ó"<ÐàˆØˆÜ# OÓ4ò 	*‰JˆAˆwØ!×.Ñ.ØØØ);Ð)GÐ" 1Ò%ÈTØ#ØØ+ð /ó ˆNð Ð%Ø%Ð1Ü—L‘LØ0°°Ð3GÐHZÐ[\ÑH]ÐG^Ð^gÐhoÐgpÐqØ#'ð !ô ñ ô —L‘LÐ#9¸!¸¸IÀgÀYÐ!OÐ\`�LÔaÙà×"Ñ" >Ô2Ø)‰Lð)	*ð, Ðr   c                 ó  — | j                  ||«      }t        |«      }t        |«      dkD  r\|j                  «       }|j                  |k(  r|S |r*| j                  ||«      }|D ]  }|j                  |«       Œ t        |«      dkD  rŒ\y rH   )r”   r   rb   rI   r�   Ú
appendleft)	r   r4   Ú
child_typer8   Ú	recursiver“   Údqr»   Úchilds	            r   Úfind_first_child_by_typez"OnnxModel.find_first_child_by_type©  s‹   € Ø×$Ñ$ TÐ+>Ó?ˆÜ�8‹_ˆÜ�"‹g˜ŠkØŸ6™6›8ˆLØ×#Ñ# zÒ1Ø#Ð#áØ×,Ñ,¨\Ð;NÓO�Ø%ò )�EØ—M‘M %Õ(ð)ô �"‹g˜‹kð r   Úedgesc                 óŽ  — |�ft        |«      t        |«      k(  sJ ‚|D ]H  }t        |t        «      r5t        |«      dk(  r't        |d   t        «      rt        |d   t        «      rŒHJ ‚ |€| j	                  «       }|}g }t        |«      D ]¸  \  }	}
d}|€| j                  ||¬«      }n| j                  ||||	   d   ¬«      }|D ]H  }|j                  |
k(  sŒ||vsŒ|�,|j                  ||	   d      |j                  ||	   d      k7  rŒF|} n |€t        j                  d|	› d|
› �d	¬
«        y|j                  |«       |}Œº |S )a¾  
        Find a sequence of input edges based on constraints on parent op_type and index.
        Note that we use greedy approach and only consider the first matched child, so it has chance to miss matching.

        Args:
            node (str): current node name.
            child_op_types (str): constraint of child node op_type of each input edge.
            edges (list): each edge is represented by two integers: output index of parent node, input index of child node.
                         None means no constraint.
            exclude(list): list of nodes that are excluded (not allowed to match as child).

        Returns:
            children: a list of matched children node.
        Né   r   r¨   )r8   )r8   r’   zFailed to match child r¶   Tr·   )rb   rN   rª   Úintr8   ra   r”   r�   r5   r<   rh   r�   r6   )r   r4   Úchild_op_typesrÅ   r8   rŸ   Úedger»   Úmatched_childrenr™   r�   Úmatched_childÚchildren_nodesrÃ   s                 r   Úmatch_child_pathzOnnxModel.match_child_path¸  s�  € ð, ÐÜ�u“:¤ ^Ó!4Ò4Ð4Ð4Øò �ä˜t¤UÔ+´°D³	¸Q²Ä:ÈdÐSTÉgÔWZÔC[Ô`jÐkoÐpqÑkrÔtwÕ`xðØxðð
 Ð&Ø"&×":Ñ":Ó"<ÐàˆØÐÜ# NÓ3ò 	)‰JˆAˆwØ ˆMàˆ}Ø!%×!2Ñ!2°<ÐUhÐ!2Ó!i‘à!%×!2Ñ!2Ø Ð6IÐX]Ð^_ÑX`ÐabÑXcð "3ó "�ð (ò �Ø—=‘= GÓ+°¸WÒ0DØÐ(¨U¯[©[¸¸q¹À!¹Ñ-EÈ×I\ÑI\Ð]bÐcdÑ]eÐfgÑ]hÑIiÒ-iØ ð %*�MÙðð Ð$Ü—‘Ð5°a°S¸	À'ÀÐKÐX\�Ô]Ùà×#Ñ# MÔ2Ø(‰Lð3	)ð6  Ðr   c                 ó6  — |€| j                  «       }| j                  ||«      }t        |«      }t        |«      dkD  r\|j	                  «       }|j
                  |k(  r|S |r*| j                  ||«      }|D ]  }|j                  |«       Œ t        |«      dkD  rŒ\y rH   )r=   r—   r   rb   rI   r�   r¿   )	r   r4   Úparent_typer=   rÁ   r–   rÂ   r»   r    s	            r   Úfind_first_parent_by_typez#OnnxModel.find_first_parent_by_type÷  s    € ØÐ&Ø"&×":Ñ":Ó"<Ðà×"Ñ" 4Ð)<Ó=ˆÜ�7‹^ˆÜ�"‹g˜ŠkØŸ6™6›8ˆLØ×#Ñ# {Ò2Ø#Ð#áØ×*Ñ*¨<Ð9LÓM�Ø%ò *�FØ—M‘M &Õ)ð*ô �"‹g˜‹kð r   c                 ó,  — | j                  d«      D ]X  }|j                  d   |k(  sŒ|j                  D ]4  }|j                  dk(  sŒt	        j
                  |j                  «      c c S  ŒZ | j                  |«      }|�t	        j
                  |«      S y )NÚConstantr   Úvalue)r�   r<   rJ   rT   r   Úto_arrayÚtr�   )r   r>   r4   Úattrx   s        r   Úget_constant_valuezOnnxModel.get_constant_value	  sŒ   € Ø×-Ñ-¨jÓ9ò 	<ˆDØ�{‰{˜1‰~ Ó,ØŸ>™>ò <�CØ—x‘x 7Ó*Ü+×4Ñ4°S·U±UÓ;Ô;ñ<ð	<ð ×*Ñ*¨;Ó7ˆØÐ"Ü×(Ñ(¨Ó5Ð5àr   c                 óp   — t        |j                  «      D ]  \  }}| j                  |«      }|€Œ||fc S  y)Nrœ   )ra   r5   rØ   )r   r4   r™   r5   rÔ   s        r   Úget_constant_inputzOnnxModel.get_constant_input  sB   € Ü! $§*¡*Ó-ò 	 ‰HˆAˆuØ×+Ñ+¨EÓ2ˆEØÑ Ø˜%�x’ð	 ð
 r   c                 ót   — | j                  |«      \  }}|�"|j                  dk(  rt        ||z
  «      |k  r|S y)Nr¨   r©   )rÚ   ÚsizeÚabs)r   r4   Úexpected_valueÚdeltar™   rÔ   s         r   Úfind_constant_inputzOnnxModel.find_constant_input  s@   € Ø×*Ñ*¨4Ó0‰ˆˆ5ØÐ §¡¨q¢´S¸ÀÑ9OÓ5PÐSXÒ5XØˆHàr   c           	      óè   — | j                  |«      }|€t        j                  |› d|› d�«       yt        |j                  «      |k7  r+t        j                  |› d|› d|› d|j                  › �«       yy)Nú z is not initializer.Fz shall have z dimensions. Got shape T)rØ   rh   r�   rb   Úshape)r   r>   Ú
dimensionsÚdescriptionrÔ   s        r   Ú$is_constant_with_specified_dimensionz.OnnxModel.is_constant_with_specified_dimension&  sw   € Ø×'Ñ'¨Ó4ˆØˆ=Ü�L‰L˜K˜=¨¨+¨Ð6JÐKÔLØäˆu�{‰{Ó˜zÒ)Ü�L‰L˜K˜=¨¨+¨°lÀ:À,ÐNeÐfk×fqÑfqÐerÐsÔtØàr   c                 ó.   — | j                  |||«      dk\  S rH   )rà   )r   r4   rÞ   rß   s       r   Úhas_constant_inputzOnnxModel.has_constant_input2  s   € Ø×'Ñ'¨¨n¸eÓDÈÑIÐIr   c                 ó\  — |€| j                  «       }||j                  d      }g }t        |«      }t        |«      dkD  rl|j	                  «       }||v rŒ#||vrD|j                  |«       |j                  D ]$  }||v sŒ||   }|D ]  }	|j                  |	«       Œ Œ& t        |«      dkD  rŒl|S rH   )r8   r<   r   rb   rI   r6   r¿   )
r   Ú	root_nodeÚ
stop_nodesr8   r“   Úunique_nodesrÂ   r»   r<   rÃ   s
             r   Úget_children_subgraph_nodesz%OnnxModel.get_children_subgraph_nodes5  sÉ   € ØÐ&Ø"&×":Ñ":Ó"<Ðà& y×'7Ñ'7¸Ñ':Ñ;ˆàˆä�8‹_ˆÜ�"‹g˜ŠkØŸ6™6›8ˆLØ˜zÑ)Øà <Ñ/Ø×#Ñ# LÔ1à*×1Ñ1ò 1�FØÐ!4Ò4Ø#6°vÑ#>˜Ø%-ò 1˜EØŸM™M¨%Õ0ñ1ð1ô �"‹g˜‹kð Ðr   c                 ó  — g }|j                   j                  D ]m  }|j                  d«      r|j                  |j                  «       Œ0|j                  d«      r|j                  |j
                  «       Œ]|j                  d«       Œo |S )zConvert tensor shape to listÚ	dim_valueÚ	dim_paramú?)rã   ÚdimÚHasFieldr6   rï   rð   )r   Útensor_typeÚ
shape_listÚds       r   Útensor_shape_to_listzOnnxModel.tensor_shape_to_listN  st   € àˆ
Ø×"Ñ"×&Ñ&ò 	'ˆAØ�z‰z˜+Ô&Ø×!Ñ! !§+¡+Õ.Ø—‘˜KÔ(Ø×!Ñ! !§+¡+Õ.à×!Ñ! #Õ&ð	'ð Ðr   rT   Úsymbolic_shape_helperc                 ó   — | j                   �€i | _         t        j                  | j                  j                  j
                  | j                  j                  j                  | j                  j                  j                  «      D ]9  }|j                  j                  j                  | j                   |j                  <   Œ; | j                  j                  j                  D ]>  }|j                  | j                   vsŒ|j                  | j                   |j                  <   Œ@ || j                   v r| j                   |   S |�=||j                  v r/|j                  |   }|j                  j                  j                  S y)zXTry get data type given a name (could be initializer, input or output of graph or node).N)r#   Ú	itertoolsÚchainr   r3   Ú
value_infor5   r<   rK   rô   Ú	elem_typerT   rx   Ú	data_typeÚ	known_vi_)r   rT   rø   rü   rx   s        r   Ú	get_dtypezOnnxModel.get_dtypeZ  sB  € ð ×ÑÑ#Ø!ˆDÔÜ'Ÿo™oØ—
‘
× Ñ ×+Ñ+Ø—
‘
× Ñ ×&Ñ&Ø—
‘
× Ñ ×'Ñ'óò Z�
ð
 5?·O±O×4OÑ4O×4YÑ4Y�× Ñ  §¡Ò1ðZð  $Ÿz™z×/Ñ/×;Ñ;ò O�Ø×#Ñ#¨4×+;Ñ+;Ò;Ø9D×9NÑ9N�D×$Ñ$ [×%5Ñ%5Ò6ðOð �4×#Ñ#Ñ#Ø×#Ñ# DÑ)Ð)à Ð,°Ð9N×9XÑ9XÑ1XØ.×8Ñ8¸Ñ>ˆJØ—?‘?×.Ñ.×8Ñ8Ð8àr   c                 óø  — | j                   �€‘i | _         t        j                  | j                  j                  j
                  | j                  j                  j                  | j                  j                  j                  «      D ]µ  }|j                  j                  j                  d«      sŒ)g }|j                  j                  j                  j                  D ]E  }|j                  r|j                  |j                  «       Œ+|j                  |j                  «       ŒG || j                   |j                   <   Œ· | j                  j                  j"                  D ]>  }|j                   | j                   vsŒ|j$                  | j                   |j                   <   Œ@ || j                   v r| j                   |   S |�=||j&                  v r/|j&                  |   }|j                  j                  j(                  S y)zTTry get shape given a name (could be initializer, input or output of graph or node).Nrã   )r$   rú   rû   r   r3   rü   r5   r<   rK   rô   ró   rã   rò   rð   r6   rï   rT   rx   Údimsrÿ   rý   )r   rT   rø   rü   rã   rò   rx   s          r   Ú	get_shapezOnnxModel.get_shapes  s›  € ð ×ÑÑ#Ø!ˆDÔÜ'Ÿo™oØ—
‘
× Ñ ×+Ñ+Ø—
‘
× Ñ ×&Ñ&Ø—
‘
× Ñ ×'Ñ'óò >�
ð
 —?‘?×.Ñ.×7Ñ7¸Õ@Ø�EØ)Ÿ™×:Ñ:×@Ñ@×DÑDò 8˜ØŸ=š=Ø!ŸL™L¨¯©Õ7à!ŸL™L¨¯©Õ7ð	8ð
 9>�D×$Ñ$ Z§_¡_Ò5ð>ð  $Ÿz™z×/Ñ/×;Ñ;ò J�Ø×#Ñ#¨4×+;Ñ+;Ò;Ø9D×9IÑ9I�D×$Ñ$ [×%5Ñ%5Ò6ðJð �4×#Ñ#Ñ#Ø×#Ñ# DÑ)Ð)à Ð,°Ð9N×9XÑ9XÑ1XØ.×8Ñ8¸Ñ>ˆJØ—?‘?×.Ñ.×8Ñ8Ð8àr   r4   Úattribute_namec                 óv   — | j                   D ]*  }|j                  |k(  sŒt        j                  |«      }|c S  y r   )rJ   rT   r   Úget_attribute_value)r4   r  rR   rÔ   s       r   Úget_node_attributezOnnxModel.get_node_attribute“  s;   € à—N‘Nò 	ˆDØ�y‰y˜NÓ*Ü×2Ñ2°4Ó8�Ø’ð	ð r   c                 óZ  — | j                  «       }d}| j                  «       D ]Z  }|j                  dk(  sŒ| j                  |d|¬«      }|sŒ*|j                  dk(  sŒ:|j                  d   |j                  d<   |dz  }Œ\ |dkD  r't
        j                  d|«       | j                  «        yy)av  Remove Cast node that are followed by another Cast node like  --> Cast --> Cast -->
        Note that this shall be used carefully since it might introduce semantic change.
        For example, float -> int -> float could get different value than the original float value.
        So, it is recommended to used only in post-processing of mixed precision conversion.
        r   ÚCast)r=   r¨   zRemoved %d cascaded Cast nodesN)r=   r2   r�   rš   r5   rh   ÚinfoÚprune_graph)r   r=   Úremoved_countr4   r    s        r   Úremove_cascaded_cast_nodesz$OnnxModel.remove_cascaded_cast_nodes›  s¥   € ð #×6Ñ6Ó8ÐØˆØ—J‘J“Lò 	'ˆDØ�|‰|˜vÓ%ØŸ™¨¨qÐFY˜ÓZ�Ú˜fŸn™n°Ó6Ø$*§L¡L°¡O�D—J‘J˜q‘MØ! QÑ&‘Mð	'ð ˜1ÒÜ�K‰KÐ8¸-ÔHØ×ÑÕð r   c                 óÖ  — | j                  d¬«      }| j                  r|€t        j                  d«       g }| j	                  «       D ]j  }|j
                  dk(  sŒ| j                  |j                  d   |«      }| j                  |j                  d   |«      }|sŒT||k(  sŒZ|j                  |«       Œl |�r2t        | j                  «       «      }t        | j                  «       «      }|D ]Û  }t        t        |j                  «      |z  «      r{t        t        |j                  «      |z  «      sYt        | j                  «       |j                  d      «      dk(  r-| j!                  |j                  d   |j                  d   «       n-ŒŸ| j#                  |j                  d   |j                  d   «       | j%                  |«       ŒÝ t        j'                  dt        |«      «       yy)	zKRemove cast nodes that are not needed: input and output has same data type.T)r/   NzFshape inference failed which might impact useless cast node detection.r	  r   r¨   z4Removed %d Cast nodes with output type same as input)r0   r!   rh   ri   r2   r�   r   r5   r<   r6   ÚsetrV   rY   Úboolrb   r8   r‹   r…   rj   r
  )r   Úshape_inferrl   r4   Úinput_dtypeÚoutput_dtypeÚgraph_input_namesÚgraph_output_namess           r   Úremove_useless_cast_nodesz#OnnxModel.remove_useless_cast_nodes®  s£  € à×.Ñ.°dÐ.Ó;ˆØ×"Ò" {Ð':Ü�N‰NÐcÔdàˆØ—J‘J“Lò 	1ˆDØ�|‰|˜vÓ%Ø"Ÿn™n¨T¯Z©Z¸©]¸KÓH�Ø#Ÿ~™~¨d¯k©k¸!©n¸kÓJ�Ú ;°,Ó#>Ø#×*Ñ*¨4Õ0ð	1ò Ü # D×$?Ñ$?Ó$AÓ BÐÜ!$ T×%AÑ%AÓ%CÓ!DÐØ'ò 
'�Üœ˜DŸK™KÓ(Ð+=Ñ=Ô>Ü ¤ T§Z¡Z£Ð3DÑ!DÔEÌ3Ø×0Ñ0Ó2°4·:±:¸a±=ÑAóLàòLð ×8Ñ8¸¿¹ÀA¹ÈÏÉÐTUÉÕWà à×3Ñ3°D·K±KÀ±NÀDÇJÁJÈqÁMÔRØ× Ñ  Õ&ð
'ô �K‰KØFÜ�OÓ$õð r   c                 óT   — t         j                  d«       | j                  d|¬«       y )NzbThe function convert_model_float32_to_float16 is deprecated. Use convert_float_to_float16 instead!T)Úuse_symbolic_shape_inferÚkeep_io_types)rh   ri   r   )r   Úcast_input_outputs     r   Ú convert_model_float32_to_float16z*OnnxModel.convert_model_float32_to_float16Ð  s'   € Ü�‰Øpô	
ð 	×%Ñ%¸tÐSdÐ%Õer   c                 ó„  — d|vrd|d<   | j                   }|�r—t        |«      }	 |j                  |dd¬«      }|��ti }|j                  j                  D ]è  }t        |j                  d«      sŒt        |j                  j                  d«      sŒ;|j                  j                  j                  t        j                  k7  sŒm|j                  sŒzt        «       }|j                  |«       t        |j                  j                  d«      r%|j                  j                  j                  d«       |||j                  <   Œê |j                  j                  D ]  }|j                  |v sŒ||j                  = Œ  |j                  «       D ]'  }|j                  j                  j!                  |«       Œ) d
|i}	|	j)                  dD �
ci c]  }
|
|v r|
||
   “Œ c}
«       t+        |fi |	¤Ž}| j-                  |«       | j/                  «        | j1                  «        y# t"        $ r t$        j'                  d	«       Y Œ‰w xY wc c}
w )aÍ	  Convert a model to half (default) or mixed precision.
           To use mixed precision, user need specify which graph inputs, outputs, operator type
           or list of nodes shall keep in float32.

           Note that the conversion might not proceed without type information for the whole graph.

           By default, we use symbolic shape inference to get type information. The benefit of symbolic shape inference
           is that it could handle fused operators in com.microsoft domain. Those operators cannot be handled in onnx shape
           inference so symbolic shape inference is recommended for optimized model.

           When symbolic shape inference is used (even if it failed), ONNX shape inference will be disabled.

           Note that onnx shape inference will fail for model larger than 2GB. For large model, you have to enable
           symbolic shape inference. If your model is not optimized, you can also use model path to call
           convert_float_to_float16 in float16.py (see https://github.com/microsoft/onnxruntime/pull/15067) to
           avoid the 2GB limit.

        Args:
            use_symbolic_shape_infer (bool, optional): use symbolic shape inference instead of onnx shape inference.
                                                       Defaults to True.
            keep_io_types (Union[bool, List[str]], optional): boolean or a list of float32 input/output names.
                                                              If True, model inputs/outputs should be left as float32.
                                                              Defaults to True.
            op_block_list (List[str], optional): List of operator types to leave as float32.
                                                 Defaults to None, which will use `float16.DEFAULT_OP_BLOCK_LIST`.
            node_block_list (List[str], optional): List of node names to leave as float32. Defaults to None.
            force_fp16_initializers(bool): force converting all float initializers to float16.
                                           Default to false.
            min_positive_val (float, optional): minimal positive value. Defaults to 1e-7.
            max_finite_val (float, optional): maximal finite value. Defaults to 1e4.
            force_fp16_inputs(Dict[str, List[int]]): Force the conversion of the inputs of some operators to float16, even if
                                                     this script's preference it to keep them in float32.
        r  TF)Ú
auto_mergeÚguess_output_rankNrô   rý   rã   ziFailed to run symbolic shape inference. Please file an issue in https://github.com/microsoft/onnxruntime.Údisable_shape_infer)r  Úmin_positive_valÚmax_finite_valÚop_block_listÚnode_block_listÚforce_fp16_initializersÚforce_fp16_inputsÚ#use_bfloat16_as_blocked_nodes_dtype)r   r   Úinfer_shapesr3   rü   ÚhasattrrK   rô   rý   r
   Ú	UNDEFINEDrT   r   ÚCopyFromÚ
ClearFieldÚvaluesr6   r*   rh   ri   r/   r   r   r  r  )r   r  Úkwargsr   r    Úmodel_with_shapeÚname_viÚviÚvi_copyÚ
parametersÚkeyÚ
fp16_models               r   r   z"OnnxModel.convert_float_to_float16Ö  s  € ðD  &Ñ(Ø&*ˆF�?Ñ#à—
‘
ˆÚ#ô ">¸eÓ!DÐðØ#5×#BÑ#BÀ5ÐUYÐmrÐ#BÓ#sÐ ð
 $Ñ/Ø �GØ.×4Ñ4×?Ñ?ò 7˜ä# B§G¡G¨]Õ;Ü '¨¯©×(;Ñ(;¸[Õ IØ "§¡× 3Ñ 3× =Ñ =Ä×AVÑAVÓ VØ "§£ä&4Ó&6˜GØ#×,Ñ,¨RÔ0Ü& w§|¡|×'?Ñ'?ÀÔIØ '§¡× 8Ñ 8× CÑ CÀGÔ LØ/6˜G B§G¡GÒ,ð7ð $Ÿk™k×4Ñ4ò 1˜ØŸ7™7 gÒ-Ø '¨¯©Ñ 0ð1ð &Ÿn™nÓ.ò :˜ØŸ™×.Ñ.×5Ñ5°bÕ9ð:ð ,Ð-EÐFˆ
Ø×Ñð	öàð ˜&‘=ð �V˜C‘[Ñ òô	
ô" .¨eÑB°zÑBˆ
Ø�‰˜
Ô#à×'Ñ'Ô)à×&Ñ&Õ(øô9 ò Ü—‘Øöðüòs8   ¥AH Á. H Â1H ÃH ÃBH Å'A	H ÇH=ÈH:È9H:c                 ó¾  — |r|j                  d«      r|n|dz   }n|dz   }d}|| j                  v r| j                  |   dz   }no| j                  «       D ]\  }|j                  sŒ|j                  j	                  |«      sŒ,	 t        |j                  t        |«      d «      }t        |dz   |«      }Œ^ || j                  |<   |t        |«      z   S # t        $ r Y Œ‡w xY w)ar  Create a unique node name that starts with a prefix (default is operator type).
           The name will not be duplicated with any name that generated or existed in current graphs.
        Args:
            op_type (str): operator type
            name_prefix (str, optional): prefix of node name. Defaults to None.

        Returns:
            str: node name
        Ú_r   r¨   N)
Úendswithr   r2   rT   Ú
startswithrÈ   rb   ÚmaxÚ
ValueErrorr~   )r   r�   Úname_prefixÚprefixÚsuffixr4   r¥   s          r   Úcreate_node_namezOnnxModel.create_node_name7  sä   € ñ Ø$/×$8Ñ$8¸Ô$=‘[ÀKÐRUÑDU‰Fà˜s‘]ˆFàˆØ�T×+Ñ+Ñ+Ø×+Ñ+¨FÑ3°aÑ7‰Fð Ÿ
™
›ò !�Ø—9“9 §¡×!5Ñ!5°fÕ!=ð!Ü # D§I¡I¬c°&«k¨mÐ$<Ó =˜Ü!$ U¨Q¡Y°Ó!7™ð	!ð *0ˆ×Ñ˜vÑ&àœ˜F›Ñ#Ð#øô &ò !Ù ð!ús   Â0CÃ	CÃCc                 ót   — | j                   j                  j                  D ]  }|j                  |k(  sŒ|c S  y r   )r   r3   r5   rT   )r   r:   r5   s      r   Úfind_graph_inputzOnnxModel.find_graph_inputZ  s7   € Ø—Z‘Z×%Ñ%×+Ñ+ò 	ˆEØ�z‰z˜ZÓ'Ø’ð	ð r   c                 ót   — | j                   j                  j                  D ]  }|j                  |k(  sŒ|c S  y r   )r   r3   r<   rT   )r   r>   r<   s      r   Úfind_graph_outputzOnnxModel.find_graph_output`  s7   € Ø—j‘j×&Ñ&×-Ñ-ò 	ˆFØ�{‰{˜kÓ)Ø’ð	ð r   c                 óJ  — |€| j                  «       }g }| j                  ||«      }t        |«      }t        |«      dkD  rc|j	                  «       }||v rŒ#||vr;|j                  |«       |j                  D ]  }||v sŒ|j                  ||   «       Œ t        |«      dkD  rŒc|S rH   )r=   r—   r   rb   rI   r6   r5   r¿   )	r   r4   rë   r=   rì   r–   rÂ   r»   r5   s	            r   Úget_parent_subgraph_nodesz#OnnxModel.get_parent_subgraph_nodesf  s¶   € ØÐ&Ø"&×":Ñ":Ó"<Ðàˆà×"Ñ" 4Ð)<Ó=ˆÜ�7‹^ˆÜ�"‹g˜ŠkØŸ6™6›8ˆLØ˜zÑ)Øà <Ñ/Ø×#Ñ# LÔ1à)×/Ñ/ò B�EØÐ 3Ò3ØŸ™Ð&9¸%Ñ&@ÕAðBô �"‹g˜‹kð Ðr   c                 ó$  — g }|j                   D ]*  }| j                  |«      sŒ||vsŒ|j                  |«       Œ, |rR| j                  |g «      }|D ];  }|j                   D ]*  }| j                  |«      sŒ||vsŒ|j                  |«       Œ, Œ= |S )z@
        Find graph inputs that linked to current node.
        )r5   r@  r6   rD  )r   r»   rÁ   Úgraph_inputsr5   Úparent_nodesr4   s          r   Úget_graph_inputszOnnxModel.get_graph_inputs|  s¥   € ð ˆØ!×'Ñ'ò 	+ˆEØ×$Ñ$ UÕ+°¸\Ò0IØ×#Ñ# EÕ*ð	+ñ Ø×9Ñ9¸,ÈÓKˆLØ$ò 3�Ø!ŸZ™Zò 3�EØ×,Ñ,¨UÕ3¸À\Ò8QØ$×+Ñ+¨EÕ2ñ3ð3ð Ðr   c                 óP   — t        |j                  «      D ]  \  }}|| k(  sŒ|c S  y)Nr©   )ra   r5   )Únode_outputÚ
child_noder¥   r5   s       r   r£   zOnnxModel.input_index�  s2   € ä% j×&6Ñ&6Ó7ò 	‰LˆE�5Ø˜Ó#Ø’ð	ð r   c                 ó>  — | j                  «       }g }| j                  «       }|D ]5  }|j                  dk(  sŒ|j                  d   |vsŒ%|j	                  |«       Œ7 | j                  |«       t        |«      dkD  r"t        j                  dt        |«      › �«       y y )NrÓ   r   zRemoved unused constant nodes: )	r8   r2   r�   r<   r6   rm   rb   rh   r�   )r   r8   Úunused_nodesr2   r4   s        r   Úremove_unused_constantz OnnxModel.remove_unused_constant”  s˜   € Ø"×6Ñ6Ó8Ðð ˆØ—
‘
“ˆØò 	*ˆDØ�|‰|˜zÓ)¨d¯k©k¸!©nÐDWÒ.WØ×#Ñ# DÕ)ð	*ð 	×Ñ˜,Ô'äˆ|Ó˜qÒ Ü�L‰LÐ:¼3¸|Ó;LÐ:MÐNÕOð !r   c                 óè   — t        «       }|j                  D ]X  }|j                  t        j                  k(  sŒ!|j
                  j                  }|D ]  }|j                  |j                  «       Œ ŒZ |S )zD
        Get inputs to all nodes in all subgraphs of a node
        )	r  rJ   rK   r   rM   rO   r4   r/   r5   )r   r4   Úsubgraph_nodes_inputsrR   Úchild_nodesrK  s         r   Ú_get_subgraph_inputs_of_nodez&OnnxModel._get_subgraph_inputs_of_node£  sm   € ô
 !$£ÐØ—N‘Nò 	CˆDØ�y‰yœN×0Ñ0Ó0Ø"Ÿf™fŸk™k�Ø"-ò C�JØ)×0Ñ0°×1AÑ1AÕBñCð	Cð
 %Ð$r   c                 óÞ   ‡— t        t        ˆfd„| j                  j                  j                  «      «      }t        «       }|D ]$  }| j                  |«      }|j                  |«       Œ& ||fS )zˆ
        Get input names to all nodes in all subgraphs where subgraphs are
        graph attributes of a node in the main graph
        c                 ó    •— | j                   ‰v S r   )r�   )r4   Úops_with_graph_attrss    €r   ú<lambda>z:OnnxModel._get_subgraph_nodes_and_inputs.<locals>.<lambda>µ  s   ø€ °$·,±,ÐBVÐ2V€ r   )r@   Úfilterr   r3   r4   r  rR  r/   )r   rU  Úsubgraph_nodesrP  Úparent_nodeÚsubgraph_inputs_of_parent_nodes    `    r   Ú_get_subgraph_nodes_and_inputsz(OnnxModel._get_subgraph_nodes_and_inputs°  sq   ø€ ô
 œfÓ%VÐX\×XbÑXb×XhÑXh×XmÑXmÓnÓoˆÜ #£ÐØ)ò 	IˆKØ-1×-NÑ-NÈ{Ó-[Ð*Ø!×(Ñ(Ð)GÕHð	Ið Ð4Ð4Ð4r   c                 óR  — |€8| j                   j                  j                  D �cg c]  }|j                  ‘Œ c}n|}| j	                  d¬«      }| j                  «       }d„ }t        | j                  «       «      dkD  r†| j                  h d£¬«      \  }}	t        |«      dk(  rt        j                  d	«       y| j                   j                  j                  D ](  }
|
|v rŒ|
j                  D ]  }||	v sŒ||vsŒ||gz  }Œ Œ* i }t        «       }|D ]  }||v sŒ|j                  ||   «       Œ t        |«      dkD  rp|j                  «       }
 ||
«      }|rG||vrC|
||<   |
j                  D ]/  }t        |«      dkD  sŒ||v sŒ||vsŒ|j!                  ||   «       Œ1 t        |«      dkD  rŒpg }d}| j                   j                  j                  D ]R  }
 ||
«      }|j#                  |«      }|r0|j$                  |
j$                  k(  r||
k(  r|j                  |
«       ŒN|dz  }ŒT d| _        | j                   j                  j)                  d
«       | j                   j                  j                  j+                  |«       g }|�{| j                   j                  j                  D ]"  }|j                  |vsŒ|j                  |«       Œ$ |D ]1  }| j                   j                  j                  j-                  |«       Œ3 g }|r‚| j	                  «       }| j                   j                  j                  D �cg c]  }|j                  |vsŒ|‘Œ }}|D ]1  }| j                   j                  j                  j-                  |«       Œ3 |s|s|dkD  r~g }|r|j                  t        |«      › d�«       |r|j                  t        |«      › d�«       |dkD  r|j                  |› d�«       t        j/                  ddj1                  |«      «       | j3                  «        yc c}w c c}w )a×  
        Prune graph to keep only required outputs. It removes unnecessary nodes that are not linked
        (directly or indirectly) to any required output.

        There is also an option to remove graph inputs that are not used to generate any required output.

        Args:
            outputs (list): a list of graph outputs to retain. If it is None, all graph outputs will be kept.
            allow_remove_graph_inputs (bool): allow remove graph inputs.
        NT)r7   c                 ó¨   — | j                   d   r| j                   d   S t        t        | j                   D �cg c]  }|sŒ|‘Œ	 c}«      d «      S c c}w rH   )r<   ÚnextÚiter)r4   Úos     r   Úget_first_outputz/OnnxModel.prune_graph.<locals>.get_first_outputÍ  sA   € Ø�{‰{˜1Š~Ø—{‘{ 1‘~Ð%Üœ¨¯©Ö: AºšaÒ:Ó;¸TÓBÐBùÒ:s
   ·A¿Ar¨   >   ÚIfÚLoopÚScan)rU  r   z)Skip prune_graph since graph has subgraphr4   z inputsz outputsz nodesz
Removed %sz, )r   r3   r<   rT   r8   r=   rb   rD   r[  rh   r�   r4   r   r6   rI   r5   r¿   Úgetr�   r"   r+  ro   rg   r
  ÚjoinÚupdate_graph)r   rc   Úallow_remove_graph_inputsr<   Úkeep_outputsÚ"input_name_to_nodes_for_main_graphr=   ra  rX  rP  r4   Úoutput_to_noderÂ   Úfirst_outputrT   Únodes_to_keepÚnum_nodes_removedÚ	kept_nodeÚoutput_to_removeÚinput_to_remover8   r5   Úremoveds                          r   r  zOnnxModel.prune_graph¼  s  € ð OVÈo°$·*±*×2BÑ2B×2IÑ2IÖJ¨˜Ÿ›ÓJÐcjˆà-1×-EÑ-EÐX\Ð-EÓ-]Ð*Ø"×6Ñ6Ó8Ðò	Cô
 ˆt�{‰{‹}Ó Ò!à48×4WÑ4WÚ%;ð 5Xó 5Ñ1ˆNÐ1ô �>Ó" aÒ'ä—‘ÐHÔIØð Ÿ
™
×(Ñ(×-Ñ-ò 
1�ð ˜>Ñ)Øð #Ÿk™kò 1�FØÐ!6Ò6¸6ÐIkÒ;kØ$¨¨Ñ0™ñ1ð
1ð ˆô ‹WˆØ"ò 	7ˆFØÐ,Ò,Ø—	‘	Ð-¨fÑ5Õ6ð	7ô �"‹g˜ŠkØ—6‘6“8ˆDÙ+¨DÓ1ˆLÙ °^Ñ!CØ/3�˜|Ñ,Ø ŸJ™Jò A�DÜ˜4“y 1“}¨$Ð2EÒ*EÈDÐXfÒLfØŸ™Ð&9¸$Ñ&?Õ@ðAô �"‹g˜‹kð ˆØÐØ—J‘J×$Ñ$×)Ñ)ò 		'ˆDÙ+¨DÓ1ˆLØ&×*Ñ*¨<Ó8ˆIñ ˜Y×.Ñ.°$·,±,Ò>À9ÐPTÒCTØ×$Ñ$ TÕ*à! QÑ&Ñ!ð		'ð ð 	Œð 	�
‰
×Ñ×#Ñ# FÔ+Ø�
‰
×Ñ×Ñ×$Ñ$ ]Ô3ð ÐØÐØŸ*™*×*Ñ*×1Ñ1ò 4�Ø—;‘; gÒ-Ø$×+Ñ+¨FÕ3ð4ð +ò 7�Ø—
‘
× Ñ ×'Ñ'×.Ñ.¨vÕ6ð7ð ˆÙ$Ø"&×":Ñ":Ó"<ÐØ26·*±*×2BÑ2B×2HÑ2HÖr¨ÈEÏJÉJÐ^qÒLqšuÐrˆOÐrØ'ò 4�Ø—
‘
× Ñ ×&Ñ&×-Ñ-¨dÕ3ð4ñ Ñ.Ð2CÀaÒ2GØˆGÙØ—‘¤# oÓ"6Ð!7°wÐ?Ô@ÙØ—‘¤#Ð&6Ó"7Ð!8¸ÐAÔBØ  1Ò$Ø—‘Ð"3Ð!4°FÐ;Ô<Ü�K‰K˜ d§i¡i°Ó&8Ô9à×ÑÕùòC Kùòf ss   ¥PÌ7P$ÍP$c                 ót  — | j                   j                  }t        «       }|j                  D ]]  }|j                  dv r"| j                  |«      }|j                  |«       |j                  dk7  sŒC|j                  |j                  «       Œ_ |rt        j                  d|› �«       g }|rS|j                  D ]"  }|j                  |vsŒ|j                  |«       Œ$ |D ]  }|j                  j                  |«       Œ |D �cg c]  }|j                  ‘Œ }	}t        j                  dt        |«      › d|	› �«       g }
g }|j                  D ]X  }|j                  |vr-| j                  |j                  «      s|
j                  |«       Œ>|j                  |j                  «       ŒZ |
D ]  }|j                  j                  |«       Œ |
D �cg c]  }|j                  ‘Œ }	}t        j                  dt        |
«      › d|	› �«       |rt        j                  d|› �«       | j!                  «        y c c}w c c}w )N)rc  rd  rb  rÓ   zremaining input names: zremove z unused inputs: z unused initializers: zremaining initializers:)r   r3   r  r4   r�   rR  r/   r5   rh   r�   rT   r6   rg   rb   rx   rB  rN  )r   Úverboserh  r3   Úremaining_input_namesr4   Úsubgraph_inputs_of_nodeÚinputs_to_remover5   Únames_to_removeÚweights_to_removeÚweights_to_keeprx   s                r   rg  zOnnxModel.update_graph+  s%  € Ø—
‘
× Ñ ˆä #£ÐØ—J‘Jò 	9ˆDØ�|‰|Ð5Ñ5à*.×*KÑ*KÈDÓ*QÐ'Ø%×,Ñ,Ð-DÔEà�|‰|˜zÓ)Ø%×,Ñ,¨T¯Z©ZÕ8ð	9ñ Ü�L‰LÐ2Ð3HÐ2IÐJÔKð ÐÙ$ØŸ™ò 3�Ø—:‘:Ð%:Ò:Ø$×+Ñ+¨EÕ2ð3ð *ò *�Ø—‘×"Ñ" 5Õ)ð*ð 4DÖD¨%˜5Ÿ:›:ÐDˆÐDÜ�‰�wœsÐ#3Ó4Ð5Ð5EÀoÐEVÐWÔXð ÐØˆØ ×,Ñ,ò 	9ˆKØ×ÑÐ'<Ñ<ÀT×E[ÑE[Ð\g×\lÑ\lÔEmØ!×(Ñ(¨Õ5à×&Ñ& {×'7Ñ'7Õ8ð		9ð
 -ò 	2ˆKØ×Ñ×$Ñ$ [Õ1ð	2ð @QÖQ°˜;×+Ó+ÐQˆÐQÜ�‰�wœsÐ#4Ó5Ð6Ð6LÈ_ÐL]Ð^Ô_ÙÜ�L‰LÐ2°?Ð2CÐDÔEà×#Ñ#Õ%ùò' Eùò Rs   ÄH0ÇH5c                 óš   — |D ]F  }|j                   D ]5  }||v rŒ||v sŒ||   D ]!  }||vsŒt        j                  d||«          y Œ7 ŒH y)Nz<it is not safe to remove nodes since output %s is used by %sFT)r<   rh   r�   )r   rl   ri  r8   r=   Únode_to_removerp  Úimpacted_nodes           r   Úis_safe_to_fuse_nodeszOnnxModel.is_safe_to_fuse_nodesX  sw   € Ø-ò 	)ˆNØ$2×$9Ñ$9ò )Ð Ø# |Ñ3Øà#Ð':Ò:Ø)<Ð=MÑ)Nò )˜Ø(°Ò?Ü"ŸL™LØ ^Ø 0Ø -ôó
 $)ñ)ñ)ð	)ð r   c                 óü  — t        «       }t        «       }g }| j                  D �cg c]  }|j                  ‘Œ }}| j                  D �cg c]  }|j                  ‘Œ }}||z   }	|r|	j	                  «        |	D ]  }
|j                  |
«       Œ d}|s| j                  nt        | j                  d„ ¬«      }d }t        |«      t        |«      k7  �r(t        |«      |k(  r�nt        |«      }t        |«      D ]æ  \  }}||v rŒt        d„ |j                  D «       «      }|dk(  rH|j                  |«       |j                  |«       |j                  D ]  }|sŒ|j                  |«       Œ Œtd}|j                  D ]  }
|
sŒ|
|vsŒd}|j                  }Œ |sH|j                  |«       |j                  |«       |j                  D ]  }|sŒ|j                  |«       Œ ŒçŒè t        |«      t        |«      k7  r�Œ(t        |«      t        | j                  «      k7  r0t        dt        |«      › d	t        | j                  «      › d
|› �«      ‚| j                  d«       | j                  j                  |«       y c c}w c c}w )Nr©   c                 ó   — | j                   S r   )rT   )Úxs    r   rV  z2OnnxModel.graph_topological_sort.<locals>.<lambda>z  s   € Ð_`×_eÑ_e€ r   ©r3  c              3   ó&   K  — | ]	  }|sŒd –— Œ y­w)r¨   N© )Ú.0r6  s     r   ú	<genexpr>z3OnnxModel.graph_topological_sort.<locals>.<genexpr>„  s   è ø€ Ò!=¨º1¤!Ñ!=ùs   ‚Šr   FTz)Graph is not a DAG: len(sorted_node_set)=z, len(graph.node)=z, failed at node r4   )r  rx   rT   r5   ÚsortÚaddr4   Úsortedrb   ra   Úsumr6   r<   ÚRuntimeErrorr+  ro   )r3   Úis_deterministicÚdeps_setÚsorted_node_setÚsorted_nodesÚinitÚinitializer_namesr5   r  rU   r:   Úsorted_node_set_lenÚgraph_nodesÚlast_node_nameÚnode_idxr4   Úinput_countr<   Úfaileds                      r   Úgraph_topological_sortz OnnxModel.graph_topological_sorti  ss  € ä“5ˆÜ›%ˆØˆà38×3DÑ3DÖE¨4˜TŸY›YÐEÐÐEØ5:·[±[ÖA¨E˜UŸZ›ZÐAÐÐAØ'Ð*;Ñ;ˆáØ×ÑÔà%ò 	%ˆJØ�L‰L˜Õ$ð	%ð !ÐÙ(8�e—j’j¼fÀUÇZÁZÑUeÔ>fˆàˆÜ�/Ó"¤c¨+Ó&6Ó6Ü�?Ó#Ð':Ò:ÙÜ"% oÓ"6ÐÜ"+¨KÓ"8ò ‘�˜$Ø˜Ñ.ØÜ!Ñ!=¨T¯Z©ZÔ!=Ó=�Ø !Ò#Ø ×'Ñ'¨Ô-Ø#×'Ñ'¨Ô1Ø"&§+¡+ò 1˜Ú!Ø$ŸL™L¨Õ0ð1ð Ø�Ø"&§*¡*ò 3�JÚ! j¸Ò&@Ø!%˜Ø)-¯©™ð3ñ Ø ×'Ñ'¨Ô-Ø#×'Ñ'¨Ô1Ø"&§+¡+ò 1˜Ú!Ø$ŸL™L¨Õ0ñ1ð ð/ô	 �/Ó"¤c¨+Ó&6Ô6ô: ˆÓ¤3 u§z¡z£?Ò2ÜØ;¼CÀÓ<PÐ;QÐQcÔdgÐhm×hrÑhrÓdsÐctð  uFð  GUð  FVð  Wóð ð 	×Ñ˜Ô Ø�
‰
×Ñ˜,Õ'ùòc FùÚAs   ¥I4ÁI9c                 óô   — 	 t         j                  | j                  j                  |«       y # t        $ rA}|r8t
        j                  d«       t         j                  | j                  ddd¬«       |‚d }~ww xY w)NzaFailed to sort graph in topological order. Dumping model to _topo_sort_failed.onnx for debugging.z_topo_sort_failed.onnxT)Úsave_as_external_dataÚall_tensors_to_one_file)r   r˜  r   r3   r‹  rh   r
  Úsave)r   rŒ  Údump_model_on_failureÚes       r   Útopological_sortzOnnxModel.topological_sort¢  sn   € ð
	Ü×,Ñ,¨T¯Z©Z×-=Ñ-=Ð?OÕPøÜò 	Ù$Ü—‘Øwôô —‘Ø—J‘JÐ 8ÐPTÐnrð ô ð ˆGûð	ús   ‚*- ­	A7¶<A2Á2A7c           	      óÂ  — t        |«      j                  j                  dd¬«       | j                  D �cg c]  }|j                  dk(  sŒ|‘Œ }}| j
                  j                  D �cg c]  }|j                  dk(  sŒ|‘Œ }	}|	r*|s(| j                  j                  «       }d|_        d|_        |�rt        |«      j                  }
|
j                  dd¬«       |dz   }|rt        |«      j                  nd }t        j                  j                  |«      r-t        j                  d|› �«       t        j                  |«       |rMt        j                  j                  |«      rRt        j                  d|› �«       t        j                  |«       n$t        j                   |
«      rt#        d|
› d	�«      ‚t%        | |d||||¬
«       y t%        | |«       y c c}w c c}w )NT)r–   Úexist_okzcom.microsoftr¨   z.datazDelete the existing onnx file: z(Delete the existing external data file: zOutput directory (z!) for external data is not empty.)rš  r›  ÚlocationÚsize_thresholdÚconvert_attribute)r   r    ÚmkdirÚopset_importÚdomainr3   r4   rˆ  ÚversionrT   Úosr­   Úexistsrh   r
  rg   Úlistdirr‹  r   )r   Úoutput_pathrš  r›  r£  r¤  ÚopsetÚms_opsetr4   Úms_nodeÚ
output_dirÚexternal_data_pathr¢  s                r   rœ  zOnnxModel.save²  sŸ  € ô 	ˆ[Ó× Ñ ×&Ñ&¨t¸dÐ&ÔCð (-×'9Ñ'9Ö]˜e¸U¿\¹\È_Ó=\’EÐ]ˆÐ]ð %*§K¡K×$4Ñ$4ÖW˜D¸¿¹ÀÓ8V’4ÐWˆÐWÙ™8Ø×&Ñ&×*Ñ*Ó,ˆEØˆEŒMØ*ˆEŒLâ ä˜kÓ*×1Ñ1ˆJØ×Ñ T°DÐÔ9Ø!,¨wÑ!6ÐÙ8O”tÐ.Ó/×4Ò4ÐUYˆHä�w‰w�~‰~˜kÔ*Ü—‘Ð=¸k¸]ÐKÔLÜ—	‘	˜+Ô&á&Ü—7‘7—>‘>Ð"4Ô5ä—K‘KÐ"JÐK]ÐJ^Ð _Ô`Ü—I‘IÐ0Õ1ä—:‘:˜jÔ)Ü&Ð);¸J¸<ÐGhÐ'iÓjÐjäØØØ&*Ø(?Ø!Ø-Ø"3öô �u˜kÕ*ùòO ^ùò Xs   µGÁ
GÁ(GÁ=Gc                 óÆ   — t         j                  d«       | j                  «        t        j	                  | j
                  |||||«       t         j                  d|› �«       y )Nz Sort graphs in topological orderzModel saved to )rh   r
  rŸ  r   rœ  r   )r   r¬  Úuse_external_data_formatr›  r£  r¤  s         r   Úsave_model_to_filezOnnxModel.save_model_to_fileç  sV   € ô 	�‰Ð6Ô7Ø×ÑÔô 	�‰Ø�J‰JØØ$Ø#ØØô	
ô 	�‰�o k ]Ð3Õ4r   c                 ó®   — g }| j                   j                  j                  D ]/  }| j                  |j                  «      �Œ|j                  |«       Œ1 |S )z[
        Returns real graph inputs (excluding initializers from older onnx model).
        )r   r3   r5   r�   rT   r6   )r   rF  r5   s      r   Ú'get_graph_inputs_excluding_initializersz1OnnxModel.get_graph_inputs_excluding_initializers   sS   € ð ˆØ—Z‘Z×%Ñ%×+Ñ+ò 	+ˆEØ×#Ñ# E§J¡JÓ/Ñ7Ø×#Ñ# EÕ*ð	+ð Ðr   c                 ó†   — | j                   j                  D ]  }|j                  dv sŒ|j                  c S  t	        d«      ‚)zÁGet opset version of onnx domain

        Raises:
            RuntimeError: ONNX model has no opset for default domain.

        Returns:
            int: opset version of onnx domain.
        )Ú zai.onnxz*ONNX model has no opset for default domain)r   r¦  r§  r¨  r‹  )r   r­  s     r   Úget_opset_versionzOnnxModel.get_opset_version
  sA   € ð —Z‘Z×,Ñ,ò 	%ˆEØ�|‰|˜Ò.Ø—}‘}Ò$ð	%ô ÐGÓHÐHr   c                 ó  — i }| j                  «       D ]?  }|r|j                  r|j                  dz   nd|j                  z   }||vrdn||   dz   ||<   ŒA t        j	                  dt        |j                  «       d„ ¬«      › �«       |S )z2
        Returns node count of operators.
        ú:r¸  r¨   z
Operators:c                 ó   — | d    | d   fS )Nr¨   r   r„  )Úkvs    r   rV  z3OnnxModel.get_operator_statistics.<locals>.<lambda>"  s   € È2ÈaÉ5È&ÐRTÐUVÑRWÈ€ r   r‚  )r2   r§  r�   rh   r
  r‰  Úitems)r   Úinclude_domainÚop_countr4   Úops        r   Úget_operator_statisticsz!OnnxModel.get_operator_statistics  s‰   € ð ˆØ—J‘J“Lò 	KˆDÙ'5¸$¿+º+�$—+‘+ Ò#È2ÐQU×Q]ÑQ]Ñ]ˆBØ "¨(Ñ 2™1¸À"¹ÈÑ9IˆH�RŠLð	Kô
 	�‰�j¤¨¯©Ó(8Ñ>XÔ!YÐ ZÐ[Ô\àˆr   ry   Úbase_dirÚreturnc                 ó*  — | j                  d«      rt        d«      ‚| j                  t        j                  k(  rt        d«      ‚| j                  }t        j                  |«      }| j                  t        j                  k(  r't        | |«      }t        t        d„ |D «       «      «      S t        | «      rt        | |«       | j                  d«      rt        | j                  «      S t        j                   | «      }t        |j#                  «       «      S )a  Converts a tensor def object to a hash for data comparison purposes.
        Args:
            tensor: a TensorProto object.
            base_dir: if external tensor exists, base_dir can help to find the path to it
        Returns:
            hash: a hash of the data.
        Úsegmentz*Currently not supporting loading segments.z4The element type in the input tensor is not defined.c              3   ó>   K  — | ]  }|j                  d «      –— Œ y­w)zutf-8N)Údecode)r…  Úss     r   r†  z)OnnxModel.to_data_hash.<locals>.<genexpr>8  s   è ø€ ÒF°A˜aŸh™h w×/ÑFùs   ‚Úraw_data)ró   r:  rþ   r
   r)  Ú	TypeErrorr   Útensor_dtype_to_fieldÚSTRINGÚgetattrÚhashrª   r   r   rÊ  r   rÕ   Útobytes)ry   rÃ  Útensor_dtypeÚstorage_fieldÚutf8_stringsÚnp_datas         r   Úto_data_hashzOnnxModel.to_data_hash&  sÜ   € ð �?‰?˜9Ô%ÜÐIÓJÐJØ×Ñœ{×4Ñ4Ò4ÜÐRÓSÐSØ×'Ñ'ˆÜ×4Ñ4°\ÓBˆà×Ñœ{×1Ñ1Ò1Ü" 6¨=Ó9ˆLÜœÑF¸ÔFÓFÓGÐGä˜fÔ%Ü)¨&°(Ô;Ø�?‰?˜:Ô&Ü˜Ÿ™Ó(Ð(ä"×+Ñ+¨FÓ3ˆGÜ˜Ÿ™Ó)Ó*Ð*r   Útensor1Útensor2Úsignature_cache1Úsignature_cache2ÚrtolÚatolc                 ó$  — |r| j                   |v r|| j                      nt        j                  | «      }|r|j                   |v r||j                      nt        j                  |«      }|�||| j                   <   |�|||j                   <   | j                  |j                  k(  rm| j                  |j                  k(  rTt        j                  | «      }t        j                  |«      }	||k(  r||	k(  j                  «       S ddlm	}
  |
||	||¬«      S y)aà  Returns True when two tensors have same value.
           Note that name can be different.

        Args:
            tensor1 (TensorProto): initializer 1
            tensor2 (TensorProto): initializer 2
            signature_cache1 (dict): Optional dictionary to store data signatures of tensor1 in order to speed up comparison.
            signature_cache2 (dict): Optional dictionary to store data signatures of tensor2 in order to speed up comparison.
            rtol (float): Optional relative difference threshold for minor precision differences
            atol (float): Optional absolute difference threshold for minor precision differences
        Returns:
            bool: True when two initializers has same value.
        r   )Úallclose)rÚ  rÛ  F)
rT   r   rÕ  rþ   r  r   rÕ   ÚallÚnumpyrÝ  )rÖ  r×  rØ  rÙ  rÚ  rÛ  Úsig1Úsig2Ún1Ún2rÝ  s              r   Úhas_same_valuezOnnxModel.has_same_valueB  s  € ñ0   G§L¡LÐ4DÑ$Dð ˜WŸ\™\Ò*ä×'Ñ'¨Ó0ð 	ñ   G§L¡LÐ4DÑ$Dð ˜WŸ\™\Ò*ä×'Ñ'¨Ó0ð 	ð
 Ð'Ø-1Ð˜WŸ\™\Ñ*ØÐ'Ø-1Ð˜WŸ\™\Ñ*Ø×Ñ × 1Ñ 1Ò1°g·l±lÀgÇlÁlÒ6RÜ×&Ñ& wÓ/ˆBÜ×&Ñ& wÓ/ˆBØ�tŠ|à˜b™—~‘~Ó'Ð'õ +á  B¨T¸Ô=Ð=àr   c                 ó°   — | j                  «       D ]-  }||j                  v sŒ|j                  j                  |«        y  t        j	                  d|«       y )NzFailed to remove initializer %s)rD   rx   rg   rh   ri   )r   ry   r3   s      r   Úremove_initializerzOnnxModel.remove_initializert  sM   € Ø—[‘[“]ò 	ˆEØ˜×*Ñ*Ò*Ø×!Ñ!×(Ñ(¨Ô0Ùð	ô 	�‰Ð8¸&ÕAr   Úcachec                 óD  — t        | j                  «       «      dkD  rt        j                  d«       t        | j                  j
                  j                  «      }dg|z  }t        |dz
  «      D ]  }||   dk\  rŒt        |dz   |«      D ]b  }t        j                  | j                  j
                  j                  |   | j                  j
                  j                  |   ||«      sŒ^|||<   Œd Œ� d}t        |«      D ]{  }||   dk\  sŒ|dz  }| j                  | j                  j
                  j                  |   j                  | j                  j
                  j                  ||      j                  «       Œ} |dkD  r | j                  «        t        d|› d�«       yy)a;  Remove initializers with duplicated values, and only keep the first one.
        It could help reduce size of models (like ALBert) with shared weights.
        If require_raw_data passed, method will only compare raw_data initializers to speed runtime
        Note: this function does not process subgraph.
        r¨   z9remove_duplicated_initializer does not process subgraphs.r©   r   zRemoved z# initializers with duplicated valueN)rb   rD   rh   ri   r   r3   rx   r   r   rä  r…   rT   rg  r+   )r   rç  Úinitializer_countÚsamer™   r‚   Úcounts          r   Úremove_duplicated_initializerz'OnnxModel.remove_duplicated_initializer{  sˆ  € ô ˆt�{‰{‹}Ó Ò!Ü�N‰NÐVÔWä §
¡
× 0Ñ 0× <Ñ <Ó=ÐàˆtÐ'Ñ'ˆÜÐ(¨1Ñ,Ó-ò 
	 ˆAØ�A‰w˜!Š|ØÜ˜1˜q™5Ð"3Ó4ò  �Ü×+Ñ+Ø—J‘J×$Ñ$×0Ñ0°Ñ3Ø—J‘J×$Ñ$×0Ñ0°Ñ3ØØõ	ð  �D˜’Gñ ð
	 ð ˆÜÐ(Ó)ò 	ˆAØ�A‰w˜!‹|Ø˜‘
�Ø×/Ñ/Ø—J‘J×$Ñ$×0Ñ0°Ñ3×8Ñ8Ø—J‘J×$Ñ$×0Ñ0°°a±Ñ9×>Ñ>õð	ð �1Š9Ø×ÑÔÜ�H˜U˜GÐ#FÐGÕHð r   r<  c                 ó–  — t        | j                  «       «      dkD  rt        j                  d«       | j                  j
                  j                  D �cg c]  }|j                  ‘Œ c}| j                  j
                  j                  D �cg c]  }|j                  ‘Œ c}z   dgz   }| j                  j
                  j                  D ]7  }|j                  |vsŒ||j                  z   |vsŒ$||j                  z   |_        Œ9 | j                  j
                  j                  D ]Ô  }t        t        |j                  «      «      D ]H  }|j                  |   |vsŒ||j                  |   z   |vsŒ*||j                  |   z   |j                  |<   ŒJ t        t        |j                  «      «      D ]H  }|j                  |   |vsŒ||j                  |   z   |vsŒ*||j                  |   z   |j                  |<   ŒJ ŒÖ | j                  j
                  j                  D ]%  }|j                  |vsŒ||j                  z   |_        Œ' yc c}w c c}w )zýAdd prefix to initializer or intermediate outputs in graph. Main graph inputs and outputs are excluded.
        It could help avoid conflicting in name of node_args when merging two graphs.
        Note: this function does not process subgraph.
        r¨   z/add_prefix_to_names does not process subgraphs.r¸  N)rb   rD   rh   ri   r   r3   r5   rT   r<   rx   r4   r   rü   )	r   r<  r™   r`  Úexcludedrx   r4   r‚   rü   s	            r   Úadd_prefix_to_nameszOnnxModel.add_prefix_to_names   sï  € ô
 ˆt�{‰{‹}Ó Ò!Ü�N‰NÐLÔMð %)§J¡J×$4Ñ$4×$:Ñ$:Ö;˜q�A—F“FÒ;ÈtÏzÉz×O_ÑO_×OfÑOfÖ>gÈ!¸q¿v»vÒ>gÑgÐkmÐjnÑnˆàŸ:™:×+Ñ+×7Ñ7ò 	AˆKØ×Ñ xÒ/Ø˜K×,Ñ,Ñ,°HÒ<Ø'-°×0@Ñ0@Ñ'@�KÕ$ð	Að
 —J‘J×$Ñ$×)Ñ)ò 	AˆDäœ3˜tŸz™z›?Ó+ò ?�Ø—:‘:˜a‘=¨Ò0Ø §
¡
¨1¡Ñ-°XÒ=Ø(.°·±¸A±Ñ(>˜Ÿ
™
 1šð?ô œ3˜tŸ{™{Ó+Ó,ò A�Ø—;‘;˜q‘>¨Ò1Ø §¡¨A¡Ñ.°hÒ>Ø)/°$·+±+¸a±.Ñ)@˜Ÿ™ AšñAð	Að Ÿ*™*×*Ñ*×5Ñ5ò 	;ˆJØ�‰ hÒ.Ø"(¨:¯?©?Ñ":�
•ñ	;ùò) <ùÒ>gs   ÁIÂIc                 óN   — | j                   j                  j                  d«       y )Nrü   )r   r3   r+  r&   s    r   Úclean_shape_inferzOnnxModel.clean_shape_inferÂ  s   € Ø�
‰
×Ñ×#Ñ# LÕ1r   c                 óR  — g }|j                  | j                  j                  «       |�r}g }|D �]o  }t        |t        «      sŒt        j                  |j                  |j                  |j                  «      D ]š  }|j                  j                  j                  t        j                  k(  r  y|j                  j                  d«      sŒS|j                  j                   j                  j                  j                  t        j                  k(  sŒ™  y |j"                  D ]"  }|j$                  t        j                  k(  sŒ!  y |j&                  D �]H  }|j(                  dk(  rB|j*                  D ]3  }|j,                  dk(  sŒ|j.                  t        j                  k(  sŒ1   y |j*                  D ]å  }|j                  t0        j2                  k(  r|j                  |j4                  «       |j6                  D ]  }|j                  |«       Œ t        |j8                  t        «      r+|j8                  j$                  t        j                  k(  r   y|j:                  D ]5  }t        |t        «      sŒ|j$                  t        j                  k(  sŒ2    y Œç �ŒK �Œr |}|r�Œ}y)z$Check whether the model uses float16TÚsequence_typer	  ÚtoF)r6   r   r3   rN   r   rú   rû   r5   r<   rü   rK   rô   rý   r
   ÚFLOAT16ró   ró  rx   rþ   r4   r�   rJ   rT   r™   r   rM   rO   rD   rÖ   Útensors)	r   ÚqueueÚ
sub_graphsr3   ÚvrÖ   r4   rR   rO   s	            r   Úuse_float16zOnnxModel.use_float16Å  s  € àˆØ�‰�T—Z‘Z×%Ñ%Ô&ÚØˆJØó !,�Ü! %¬Ô4Øä"Ÿ™¨¯©°e·l±lÀE×DTÑDTÓUò (�AØ—v‘v×)Ñ)×3Ñ3´{×7JÑ7JÒJÚ#Ø—v‘v—‘ Õ7ØŸ6™6×/Ñ/×9Ñ9×EÑE×OÑOÔS^×SfÑSfÓfÚ#'ð(ð ×*Ñ*ò $�AØ—{‘{¤k×&9Ñ&9Ó9Ú#ð$ð "ŸJ™Jó ,�DØ—|‘| vÒ-Ø$(§N¡Nò ,˜DØ#Ÿy™y¨DÓ0°T·V±V¼{×?RÑ?RÓ5RÛ'+ð,ð !%§¡ò ,˜ØŸ9™9¬×(<Ñ(<Ò<Ø&×-Ñ-¨d¯f©fÔ5à!%§¡ò 1˜AØ&×-Ñ-¨aÕ0ð1ô & d§f¡f¬kÔ:¸t¿v¹v×?OÑ?OÔS^×SfÑSfÒ?fÛ#'à!%§¡ò ,˜AÜ)¨!¬[Õ9¸a¿k¹kÌ[×M`ÑM`Ó>`Ü'+ñ,ò,ò,ð!,ðF ˆEóK ðN r   Úgraph_inputÚnew_typec                 ó  — t        |t        «      sJ ‚| j                  |j                  «      sJ ‚|j                  j
                  j                  t        |«      k(  rdg fS | j                  «       }d}g }| j                  «       }|j                  |v �rÊ||j                     }|D �cg c]  }|j                  dk7  sŒ|‘Œ }	}|	ræ| j                  d«      }
|
dz   |j                  z   }|j                  j                  «       }|j                  |«       ||_        t        j                   d|j                  g|gt        |j                  j
                  j                  «      |
¬«      }|j"                  j%                  |g«       |	D ]#  }t&        j)                  ||j                  |«       Œ% |D �cg c]  }|j                  dk(  sŒ|‘Œ }}|D ]}  }t&        j+                  |d«      t        |«      k(  r)| j-                  |j.                  d   |j                  «       | j1                  |j.                  d   «      rŒm|j3                  |«       Œ |r| j5                  |«       t        |«      |j                  j
                  _        ||fS c c}w c c}w )aq  Change graph input type, and add Cast node if needed.

        Args:
            graph_input (ValueInfoProto): input of the graph
            new_type (int): new data type like TensorProto.INT32.

        Returns:
            NodeProto: a new Cast node that added. None if Cast node is not added.
            List[NodeProto]: Cast nodes that have been removed.
        Nr	  r6  ©rô  rT   rô  r   )rN   r   r@  rT   rK   rô   rý   rÈ   r3   r8   r�   r>  rü   rˆ  r*  r   Ú	make_noder4   ro   r   rƒ   r  r…   r<   rB  r6   rm   )r   rû  rü  r3   Únew_cast_noderl   r8   r2   r4   Únodes_not_castÚ	node_namer>   Únew_value_infoÚ
nodes_casts                 r   Úchange_graph_input_typez!OnnxModel.change_graph_input_typeò  sU  € ô ˜+¤~Ô6Ð6Ð6Ø×$Ñ$ [×%5Ñ%5Ô6Ð6Ð6à×Ñ×'Ñ'×1Ñ1´S¸³]ÒBØ˜�8ˆOà—
‘
“ˆØˆØˆà"×6Ñ6Ó8ÐØ×ÑÐ2Ò2Ø'¨×(8Ñ(8Ñ9ˆEð 05ÖO t¸¿¹ÈÓ8NšdÐOˆNÐOÙØ ×1Ñ1°&Ó9�	Ø'¨#™o°×0@Ñ0@Ñ@�Ø!&×!1Ñ!1×!5Ñ!5Ó!7�Ø×'Ñ'¨Ô4Ø&1�Ô#Ü &× 0Ñ 0ØØ ×%Ñ%Ð&Ø �MÜ˜;×+Ñ+×7Ñ7×AÑAÓBØ"ô!�ð —
‘
×!Ñ! = /Ô2à*ò V�DÜ×0Ñ0°°{×7GÑ7GÈÕUðVð
 ,1ÖK 4°D·L±LÀFÓ4Jš$ÐKˆJÐKØ"ò 1�Ü×/Ñ/°°dÓ;¼sÀ8»}ÒLØ×3Ñ3°D·K±KÀ±NÀK×DTÑDTÔUØ×-Ñ-¨d¯k©k¸!©nÕ=Ø#×*Ñ*¨4Õ0ð	1ñ
 Ø×!Ñ! /Ô2ä14°X³ˆ×Ñ×$Ñ$Ô.Ø˜oÐ-Ð-ùò? Pùò* Ls   Â&JÂ;JÆ-J
ÇJ
Úgraph_outputc                 ó¢  — t        |t        «      sJ ‚| j                  |j                  «      sJ ‚|j                  j
                  j                  t        |«      k(  ryd}| j                  «       }| j                  d«      }|dz   |j                  z   }| j                  |j                  |«       |j                  j                  «       }|j                  |«       ||_        t        j                  d|g|j                  gt        |«      |¬«      }|j                   j#                  |g«       t        |«      |j                  j
                  _        |S )a!  Change graph input type, and add Cast node if needed.

        Args:
            graph_input (str | ValueInfoProto): output of the graph
            new_type (int): new data type.

        Returns:
            NodeProto: a new Cast node that added. None if Cast node is not added.
        Nr	  r6  rþ  )rN   r   rB  rT   rK   rô   rý   rÈ   r3   r>  r…   rü   rˆ  r*  r   rÿ  r4   ro   )r   r  rü  Ú	cast_noder3   r  r:   r  s           r   Úchange_graph_output_typez"OnnxModel.change_graph_output_type1  s'  € ô ˜,¬Ô7Ð7Ð7Ø×%Ñ% l×&7Ñ&7Ô8Ð8Ð8à×Ñ×(Ñ(×2Ñ2´c¸(³mÒCØàˆ	Ø—
‘
“ˆð ×)Ñ)¨&Ó1ˆ	Ø ‘_ |×'8Ñ'8Ñ8ˆ
Ø×'Ñ'¨×(9Ñ(9¸:ÔFØ×)Ñ)×-Ñ-Ó/ˆØ×Ñ Ô-Ø(ˆÔÜ×$Ñ$ØØˆLØ×ÑÐÜ�8‹}Øô
ˆ	ð 	�
‰
×Ñ˜9˜+Ô&Ü25°h³-ˆ×Ñ×%Ñ%Ô/ØÐr   Úold_nameÚnew_namec                 ó$  — || j                  «       v rt        d«      ‚| j                  «       }|j                  D ]T  }|j                  |k(  sŒt
        j                  d||«       | j                  ||«       | j                  ||«       ||_        ŒV y )Nz{new_name} exists in graphz!replace output name from %s to %s)	r=   r‹  r3   r<   rT   rh   r�   r…   r‹   )r   r
  r  r3   r<   s        r   Úrename_graph_outputzOnnxModel.rename_graph_outputZ  s�   € Ø�t×/Ñ/Ó1Ñ1ÜÐ;Ó<Ð<à—
‘
“ˆØ—l‘lò 	'ˆFØ�{‰{˜hÓ&Ü—‘Ð@À(ÈHÔUØ×/Ñ/°¸(ÔCØ×0Ñ0°¸8ÔDØ&�•ñ	'r   )Fr   rœ   )NNNr   )g�íµ ÷Æ°>)T)FF)FTi   F)r¸  )NNgñhãˆµøä>g:Œ0âŽyE>)`Ú__name__Ú
__module__Ú__qualname__r   r   r'   r0   r8   r=   rA   r2   r3   rD   rV   rY   r\   r_   re   rj   rm   rr   rv   rz   r|   Ústaticmethodrƒ   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  r   r>  r@  rB  rD  rH  r£   rN  rR  r[  r  rg  r~  r˜  rŸ  rœ  r´  r¶  r¹  rÂ  r
   rÕ  ÚdictÚfloatr  rä  ræ  rì  rï  rñ  rú  r   r  r	  r  r„  r   r   r   r      s~  „ òò8ò(ð 8:À%ó ó
#ó#òòò òò&òòòòò9ò#ó0ó0ó/ó(ð ñ/ó ð/òOð ñ1ó ð1òRòòóó"ó*ð UWó ð6 Ø ØØó0òdò
0ð   Ø Øó6ópð& /3Ø Øñ= ð �E˜#˜s˜(‘OÑ$ tÑ+ó	= ó~ò$òóò
óJóò2
ñ˜cð Ð:VÐY]Ñ:]ó ñ2˜cð Ð:VÐY]Ñ:]ó ð@ ð ð ¸Cò ó ðòò& óDfó_)óB!$òFòóó,ð" ñó ðòPò%ò
5ómó^+&òZð" ò6(ó ð6(ópð  ð $Ø $ØØò2+ó ð2+ðn "'Ø $ØØó5ò2òIóð ñ+˜[ð +°Cð +Àò +ó ð+ð6 ð )-Ø(,ØØñ/Øð/àð/ð  ™+ð/ð  ™+ð	/ð
 ð/ð ð/ð 
ò/ó ð/òbBð#I°4¸$±;ó #IðJ ;¨#ó  ;òD2ò+ðZ=.à#ð=.ð ó=.ð~'à$ð'ð ó'ðR
'¨Cð 
'¸3ô 
'r   r   )rú   Úloggingr©  r,   Úcollectionsr   Úpathlibr   Úfloat16r   Úonnxr   r   r   r	   r
   r   r   r   r   Úonnx.external_data_helperr   r   r    r   Ú	getLoggerr  rh   r   r„  r   r   ú<module>r     sR   ðó Û Û 	Û 
Ý Ý å ,÷
÷ 
õ 
÷ XÝ ;à	ˆ×	Ñ	˜8Ó	$€÷E'ò E'r   