Ë
    g^(h<K  ã                   ó  — d dl Z d dlZd dlmZmZ d dlZd dlmZmZ d dl	m
Z
 d dlmZ d dlmZmZ ddlmZmZ dd	lmZmZ dd
lmZmZmZ ej4                  j6                  Zdedee   fd„Z G d„ d«      Z G d„ de «      Z! G d„ dejD                  «      Z#dedededede$e%eef      de#fd„Z&dedede'e(e$e   f   de$e(   de(f
d„Z)dededee   fd„Z*	 	 d"dededee'e(e$e   f      d ee'e(e$e   f      de'e(e%eef   f   f
d!„Z+y)#é    N)ÚAnyÚOptional)ÚFakeQuantizeBaseÚObserverBase)Úgetattr_from_fqn)ÚGraphModule)ÚGraphÚNodeé   )Ú$get_base_name_to_sets_of_related_opsÚget_unmatchable_types_map)ÚNSNodeTargetTypeÚ
NSSubgraph)Ú end_node_matches_reversed_fusionÚget_reversed_fusionsÚget_type_a_related_to_bÚgÚreturnc                 ó`   — | j                   D �cg c]  }|j                  dk(  sŒ|‘Œ c}S c c}w )NÚoutput)ÚnodesÚop)r   Úns     úZ/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/ao/ns/fx/graph_matcher.pyÚ_get_output_nodesr      s%   € Ø—w‘wÖ3�! !§$¡$¨(Ó"2ŠAÒ3Ð3ùÒ3s   �+¤+c            	       ól   — e Zd ZdZdedee   dee   dee   fd„Zd„ Zde	fd	„Z
d
eddfd„Zdedefd„Zy)Ú"_NSGraphMatchableSubgraphsIteratorzø
    Iterates through the graph of gm, starting with the output nodes
    and continuing backwards.
    1. Returns matchable subgraphs, in order. A subgraph is defined by
       (start_node, end_node).
    2. Skips over non-matchable subgraphs
    ÚgmÚnon_matchable_functionsÚnon_matchable_modulesÚnon_matchable_methodsc                 óæ   — || _         || _        || _        || _        t	        «       | _        g | _        t        | j                   j                  «      D ]  }| j                  j                  |«       Œ y ©N)
r   r   r    r!   ÚsetÚ
seen_nodesÚstackr   ÚgraphÚappend)Úselfr   r   r    r!   Ú
start_nodes         r   Ú__init__z+_NSGraphMatchableSubgraphsIterator.__init__%   sa   € ð  "ˆŒØ>UˆÔ$Ø<QˆÔ"Ø<QˆÔ"Ü%(£UˆŒØ!#ˆŒ
Ü+¨D¯G©G¯M©MÓ:ò 	*ˆJØ�J‰J×Ñ˜jÕ)ñ	*ó    c                 ó   — | S r#   © )r)   s    r   Ú__iter__z+_NSGraphMatchableSubgraphsIterator.__iter__5   s   € Øˆr,   r   c                 ó  — t        | j                  «      dkD  �rm| j                  j                  «       }|| j                  v rŒB|}|}t	        «       D ]Š  \  }}t        ||| j                  | j                  «      }|sŒ+t        t        |«      dz
  «      D ]E  }| j                  j                  |«       |j                  d   }t        |«      dz
  |z
  }||k(  sŒD|}ŒG  n | j                  j                  |«       |j                  D ]  }	| j                  |	«       Œ | j                  |«      s�Œ-|j                  dk(  r<||u r8t        | j                  |j                  «      }
t!        |
t"        t$        f«      r�Œxt'        |||¬«      S t(        ‚)z6
        Returns the next matchable subgraph.
        r   r   é   Úcall_module)r*   Úend_nodeÚbase_op_node)Úlenr&   Úpopr%   r   r   r   ÚrangeÚaddÚargsÚall_input_nodesÚ"_recursively_add_node_arg_to_stackÚ_is_matchabler   r   ÚtargetÚ
isinstancer   r   r   ÚStopIteration)r)   Úcur_end_nodeÚcur_start_nodeÚcur_base_op_nodeÚ_reverse_fusion_opsÚbase_op_idxÚis_matchÚrev_fusion_idxÚrev_base_op_idxÚargÚ	maybe_obss              r   Ú__next__z+_NSGraphMatchableSubgraphsIterator.__next__8   s�  € ô �$—*‘*‹o Ó!ØŸ:™:Ÿ>™>Ó+ˆLØ˜tŸ™Ñ.Øð *ˆNð  ,Ðô 5IÓ4Jò Ñ0Ð# [Ü;Ø Ð"5°t·w±wÀÇÁó�ò ä*/´Ð4GÓ0HÈ1Ñ0LÓ*Mò >˜ØŸ™×+Ñ+¨NÔ;ð *8×)<Ñ)<¸QÑ)?˜ä*-Ð.AÓ*BÀQÑ*FÈÑ*T˜Ø)¨_Ó<Ø/=Ñ,ð>ñ ðð" �O‰O×Ñ Ô/à%×5Ñ5ò =�Ø×7Ñ7¸Õ<ð=ð ×%Ñ%Ð&6Ô7Ùð �‰ -Ò/°NÀlÑ4RÜ,¨T¯W©W°l×6IÑ6IÓJ�	Ü˜i¬,Ô8HÐ)IÔJÙäØ)Ø%Ø-ôð ô Ðr,   rH   Nc                 ó¶  — t        |t        «      r| j                  j                  |«       yt        |t        j
                  j                  j                  «      st        |«      t        u r|D ]  }| j                  |«       Œ yt        |t        j
                  j                  j                  «      r'|j                  «       D ]  }| j                  |«       Œ yy)z}
        Adds all of the nodes in this arg to the stack, properly navigating
        through list, dicts and tuples.
        N)r>   r
   r&   r(   ÚtorchÚfxÚimmutable_collectionsÚimmutable_listÚtypeÚtupler;   Úimmutable_dictÚvalues)r)   rH   Ú	inner_argÚvalues       r   r;   zE_NSGraphMatchableSubgraphsIterator._recursively_add_node_arg_to_stack~   s¨   € ô
 �cœ4Ô Ø�J‰J×Ñ˜cÕ"ä�sœEŸH™H×:Ñ:×IÑIÔJÜ�C‹yœEÑ!à ò C�	Ø×7Ñ7¸	ÕBñCä˜œUŸX™X×;Ñ;×JÑJÔKØŸ™›ò ?�Ø×7Ñ7¸Õ>ñ?ð Lr,   Únodec                 óv  ‡— |j                   dk(  r|j                  | j                  vS |j                   dk(  r[t        |j                  t        «      sJ ‚t        | j                  |j                  «      Št        ˆfd„| j                  D «       «       S |j                   dk(  r|j                  | j                  vS y)NÚcall_functionr2   c              3   ó6   •K  — | ]  }t        ‰|«      –— Œ y ­wr#   )r>   )Ú.0ÚtÚ
target_mods     €r   ú	<genexpr>zC_NSGraphMatchableSubgraphsIterator._is_matchable.<locals>.<genexpr>•   s    øè ø€ ò àô ˜: q×)ñùs   ƒÚcall_methodF)
r   r=   r   r>   Ústrr   r   Úanyr    r!   )r)   rV   r\   s     @r   r<   z0_NSGraphMatchableSubgraphsIterator._is_matchable�   s£   ø€ Ø�7‰7�oÒ%Ø—;‘; d×&BÑ&BÐBÐBØ�W‰W˜Ò%Ü˜dŸk™k¬3Ô/Ð/Ð/Ü)¨$¯'©'°4·;±;Ó?ˆJÜó à×3Ñ3ôó ð ð ð �W‰W˜Ò%Ø—;‘; d×&@Ñ&@Ð@Ð@àr,   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r$   r   r+   r/   r   rJ   r   r;   r
   Úboolr<   r.   r,   r   r   r      s~   „ ñð*àð*ð "%Ð%5Ñ!6ð*ð  #Ð#3Ñ4ð	*ð
  #Ð#3Ñ4ó*ò ðD˜*ó DðL?°cð ?¸dó ?ð" $ð ¨4ô r,   r   c                   ó   — e Zd ZdZy)ÚGraphMatchingExceptionz=
    Exception raised when two graphs cannot be matched.
    N)ra   rb   rc   rd   r.   r,   r   rg   rg   Ÿ   s   „ òr,   rg   c                   ó”   — e Zd Z ej                  «       Z ej                  «       Z ej                  «       Z ej                  «       Zy)ÚSubgraphTypeRelationshipN)	ra   rb   rc   ÚenumÚautoÚEQUALÚEQUAL_BUT_UKNOWNÚRELATED_BUT_NOT_EQUALÚNOT_RELATEDr.   r,   r   ri   ri   ¥   s>   „ ð ˆD�I‰I‹K€Eð !�t—y‘y“{Ðð &˜DŸI™I›KÐà�$—)‘)“+�Kr,   ri   Ú
subgraph_aÚ
subgraph_bÚgm_aÚgm_bÚtype_a_related_to_bc                 ó„  — | j                   }|j                   }|j                  |j                  k7  r,|j                  dv r|j                  dv st        j                  S |j                  dv �r|j                  |j                  f}||vr9|j                  |j                  k(  rt        j
                  S t        j                  S |j                  |j                  k(  r~| j                   | j                  k(  }|j                   |j                  k(  }	|r|	st        j                  S |s|	rt        j                  S |s|	st        j                  S t        j                  S ||v rt        j                  S t        j                  S |j                  dk(  �r%| j                   | j                  k(  r|j                   |j                  k(  sJ d«       ‚t        |j                  t        «      sJ ‚t        ||j                  «      }
t        |j                  t        «      sJ ‚t        ||j                  «      }t        |
«      t        |«      f}||vr7t        |
«      t        |«      k(  rt        j
                  S t        j                  S t        |
«      t        |«      k(  rt        j                  S t        j                  S t        j                  S )N©rX   r^   r2   zSMatching call_module patterns where base_op_node != start_node is not supported yet)r4   r   ri   ro   r=   rm   r*   rn   rl   r>   r_   r   rP   )rp   rq   rr   rs   rt   Únode_aÚnode_bÚkeyÚnode_a_has_prevÚnode_b_has_prevÚmod_aÚmod_bs               r   Ú_get_subgraph_relationship_typer~   ³   sO  € ð ×$Ñ$€FØ×$Ñ$€Fð ‡y�y�F—I‘IÒà�I‰IÐ9Ñ9Ø—	‘	Ð=Ñ=ä+×7Ñ7Ð7à‡y�yÐ4Ò4Ø�}‰}˜fŸm™mÐ,ˆàÐ)Ñ)Ø�}‰} §¡Ò-Ü/×@Ñ@Ð@ä/×;Ñ;Ð;ð �=‰=˜FŸM™MÒ)Ø(×5Ñ5¸×9NÑ9NÑNˆOØ(×5Ñ5¸×9NÑ9NÑNˆOÙ©Ü/×EÑEÐEÙ%©?Ü/×EÑEÐEÙ%±Ü/×5Ñ5Ð5ô 0×5Ñ5Ð5àÐ%Ñ%Ü+×AÑAÐAä+×7Ñ7Ð7Ø	�‰�mÓ	#à×#Ñ# z×'<Ñ'<Ò<Ø×'Ñ'¨:×+@Ñ+@Ò@ð	að aó	aðAô ˜&Ÿ-™-¬Ô-Ð-Ð-Ü   v§}¡}Ó5ˆÜ˜&Ÿ-™-¬Ô-Ð-Ð-Ü   v§}¡}Ó5ˆä�E‹{œD ›KÐ(ˆàÐ)Ñ)Ü�E‹{œd 5›kÒ)Ü/×@Ñ@Ð@ä/×;Ñ;Ð;Ü�%‹[œD ›KÒ'Ü+×1Ñ1Ð1ä+×AÑAÐAä#×/Ñ/Ð/r,   Ú base_name_to_sets_of_related_opsÚexisting_namesc                 ó  — t        | j                  |«      }d}|j                  «       D ]  \  }}||v sŒ|}Œ dt        |«      z   }d}	|dz   t        |	«      z   }
|
|v r|	dz  }	|dz   t        |	«      z   }
|
|v rŒ|j	                  |
«       |
S )a;  
    Returns a unique name for a subgraph. This name is based on two things:
    1. the name of the set containing the underlying type of the base op in the
       subgraph (i.e. 'torch.nn.functional.linear' if this is related to a linear op)
    2. the number of previous subgraphs with related underlying type of the base op

    For example, in the graph

    linear0 -> relu0 -> linear1 -> relu1

    The subgraphs are (linear0, relu0) and (linear1, relu1).  If we iterate
    from the output node backwards, the name given to (linear1, relu1) will be
    `base_op_torch.nn.functional.linear_0`, and the name given to (linear0, relu0)
    will be `base_op_torch.nn.functional.linear_1`.

    Why are we not just using the node name? Answer: because of two requirements:
    A. fusions must be supported
    B. some Numeric Suite APIs can be called without having all of the models in memory

    For example, let's say we need to match nodes of

    (1) ... -> linear0 -> relu0 -> ...

    And

    (2) ... -> linear_relu0 -> ...

    Without being able to inspect them together. With the current naming scheme, if
    we iterate through both of these graphs in the same order, and assuming the rest
    of the graphs match, both of these subgraphs will get the same name without
    (1) and (2) knowing anything about each other.
    NÚbase_op_r   Ú_r   )Ú_get_node_target_typer4   Úitemsr_   r8   )rp   rr   r   r€   Útarget_typeÚtarget_base_typeÚ	base_nameÚsets_of_related_opsÚtarget_base_nameÚcounterÚproposed_names              r   Ú_get_name_for_subgraphr�   ú   s¹   € ôL (¨
×(?Ñ(?ÀÓF€KØÐØ*J×*PÑ*PÓ*Rò )Ñ&ˆ	Ð&ØÐ-Ò-Ø(Ñð)ð "¤CÐ(8Ó$9Ñ9ÐØ€GØ$ sÑ*¬S°«\Ñ9€MØ
˜>Ñ
)Ø�1‰ˆØ(¨3Ñ.´°W³Ñ=ˆð ˜>Ò
)ð ×Ñ�}Ô%ØÐr,   rV   r   c                 óÐ   — | j                   dv r| j                  S | j                   dk(  r=t        | j                  t        «      sJ ‚t	        || j                  «      }t        |«      S y )Nrv   r2   )r   r=   r>   r_   r   rP   )rV   r   Úmods      r   r„   r„   /  sV   € Ø‡w�wÐ2Ñ2Ø�{‰{ÐØ	�‰�MÒ	!Ü˜$Ÿ+™+¤sÔ+Ð+Ð+Ü˜r 4§;¡;Ó/ˆÜ�C‹yÐØr,   Úunmatchable_types_mapc           	      ó–  — |€
t        «       }|d   }|d   }|d   }t        | |||«      }t        ||||«      }t        j                  «       }	|€
t	        «       }t        |«      }
t        «       }t        «       }	 d\  }}	 t        |«      }	 t        |«      }d\  }}|�t        |j                  | «      }|�t        |j                  |«      }|�‰|�‡t        ||| ||
«      }|t        j                  k(  rd|› d|› d|› d|› d�	}t        |«      ‚|t        j                  k(  rŒ§t!        || ||«      }t!        ||||«      }||k(  sJ d	|› d
|› d�«       ‚||f|	|<   ŒÞ|€|€nd|› d|› d|› d|› d�	}t        |«      ‚t        j                  t#        t%        |	j'                  «       «      «      «      }	|	S # t        $ r Y �Œ.w xY w# t        $ r Y �Œ2w xY w)a(	  
    Matches matchable subgraphs of graph_a to graph_b.

    For a node, "matchable" is defined as a node which is not an observer,
    fake_quants, quant or dequant.

    A subgraph can contain one or more nodes.  A subgraph is matchable if
    at least one node inside of it is matchable.  Currently, all nodes in
    a subgraph must be matchable (because we assume no observers will be
    inserted in the middle of a fusion).

    A subgraph is defined by (start_node, end_node).  We assume that only
    start_node and end_node are linked with the surrounding graph, all other
    nodes in a subgraph are self-contained.

    A pair of nodes is "related" if both nodes represent the same mathematical
    operation across different quantization flavors. For example,
    `F.linear` and `torch.ops.quantized.linear` are related, and
    `F.linear` and `torch.nn.Conv` are not related.

    For each matchable pair of nodes node_a and node_b, they will match
    if node_a and node_b are related.

    For graphs A and B, they will match iff:
    1. the number of matchable subgraphs in A and B is equivalent
    2. when iterating through the matchable subgraphs of A and B in the same order, each
       corresponding pair of base nodes is related.

    This enables us to find the corresponding subgraphs between
    graphs of related models.  For example, if we had two graphs such as:

    graph_a: x0 -> conv_0 (type: nn.Conv2d) -> obs_0 -> x1
             w  -/
             b  -/

    graph_b: x0 -> quant_0 -> qconv_0 (type: nnq.Conv2d) -> dequant_0 -> x1
           packed_params_0 -/

    This function will return the following result:
    {
        'conv_0': (  # the name of the node in graph_b
          (conv_0, conv_0),  # (start_node_a, end_node_a)
          (qconv_0, qconv_0),  # (start_node_b, end_node_b)
        ),
    }

    Or, if we have a fusion pattern,

    graph_a: x0 -> linear_0 -> relu_0 -> obs_0 -> x1
             w  -/
             b  -/

    graph_b: x0 -> quant_0 -> linear_relu_0 -> dequant_0 -> x1
           packed_params_0 -/

    This function will return the following result:
    {
        'linear_relu_0': (  # the name of the node in graph_b
          (linear_0, relu_0),  # (start_node_a, end_node_a)
          (linear_relu_0, linear_relu_0),  # (start_node_b, end_node_b)
        ),
    }
    Úfuns_unmatchableÚmods_unmatchableÚmeths_unmatchable©NNz
The subgraphs
(z, z) and
(z˜)
are not related. Please ensure that the two models you pass in have the same number
of subgraphs, and each pair of subgraphs is related to each other.zSubgraph names z and z do not matchz
Attempting to match
(zj),
one of which is empty. Please ensure that the two models you pass in have the same number
of subgraphs.)r   r   ÚcollectionsÚOrderedDictr   r   r$   Únextr?   r„   r*   r~   ri   ro   rg   rm   r�   ÚreversedÚlistr…   )rr   rs   r   r�   r   r    r!   Úgraph_a_iteratorÚgraph_b_iteratorÚresultsrt   Úexisting_names_aÚexisting_names_bÚcur_subgraph_aÚcur_subgraph_bÚtype_start_aÚtype_start_bÚsubgraph_relationshipÚmsgÚ
key_name_aÚ
key_name_bs                        r   Úget_matching_subgraph_pairsr¨   9  s”  € ðJ Ð$Ü 9Ó ;ÐØ3Ð4FÑGÐØ1Ð2DÑEÐØ1Ð2EÑFÐä9ØÐ%Ð'<Ð>SóÐô :ØÐ%Ð'<Ð>SóÐô ×%Ñ%Ó'€GØ'Ð/Ü+OÓ+QÐ(Ü1Ð2RÓSÐä!$£ÐÜ!$£Ðà
à)3Ñ&ˆ˜ð	Ü!Ð"2Ó3ˆNð	Ü!Ð"2Ó3ˆNð
 &0Ñ"ˆ�lØÐ%Ü0°×1JÑ1JÈDÓQˆLØÐ%Ü0°×1JÑ1JÈDÓQˆLð Ð%¨.Ð*Dô
 %DØ °°dÐ<Oó%Ð!ð %Ô(@×(LÑ(LÒLðàÐ��L�>ð "ØÐ��L�>ð "CðF�ô -¨SÓ1Ð1Ø&Ô*B×*SÑ*SÒSàÜ/Ø Ð&FÐHXóˆJô 0Ø Ð&FÐHXóˆJð ˜jÒ(ðLà   ¨E°*°¸]ÐKóLØ(à#1°>Ð"BˆG�JÑØØÐ#¨Ð(>àðàÐ��L�>ð "ØÐ��L�>ð "ðˆCô )¨Ó-Ð-ô
 ×%Ñ%¤h¬t°G·M±M³OÓ/DÓ&EÓF€Gà€Nøô ò 	Úð	ûô ò 	Úð	ús$   Á>F+ Â
F; Æ+	F8Æ7F8Æ;	GÇGr•   ),r–   rj   Útypingr   r   rL   Útorch.ao.quantizationr   r   Útorch.ao.quantization.utilsr   Útorch.fxr   Útorch.fx.graphr	   r
   Úmappingsr   r   Úns_typesr   r   Úpattern_utilsr   r   r   ÚopsÚ	quantizedÚtoqrš   r   r   Ú	Exceptionrg   ÚEnumri   r$   rQ   r~   Údictr_   r�   r„   r¨   r.   r,   r   ú<module>r·      s½  ðã Û ß  ã ß @Ý 8Ý  ß &ç Uß 2÷ñ ð ‡i�i×Ñ€ð4˜ð 4 4¨¡:ó 4÷@ñ @ôF˜Yô ô˜tŸy™yô ðD0ØðD0àðD0ð ðD0ð ð	D0ð
 ˜UÐ#3Ð5EÐ#EÑFÑGðD0ð óD0ðN2Øð2à
ð2ð '+¨3°Ð4DÑ0EÐ+EÑ&Fð2ð ˜‘Hð	2ð
 	ó2ðj ð ¨+ð ¸(ÐCSÑ:Tó ð TXØHLñ	]Ø
ð]à
ð]ð '/¨t°C¸Ð=MÑ9NÐ4NÑ/OÑ&Pð]ð $ D¨¨cÐ2BÑ.CÐ)CÑ$DÑEð	]ð
 
ˆ#ˆu�Z Ð+Ñ,Ð
,Ñ-ô]r,   