Ë
    f^(h«D  ã                   ó„  — d dl Z d dlZd dlZd dlmZ d dlmZ d dlZd dlm	c m
Z d dlmc m
Z d dlmZmZmZ d dlmZmZ d dlmZmZ  e j2                  e«      Zdej                  j8                  deej                  j8                     fd	„Zd
ej                  j8                  ddfd„Zdej                  j@                  ddfd„Z!dej                  j@                  dede"e#ej                  j8                  f   de$e%ej                  j8                     e"e#ej                  j8                  f   f   fd„Z&dej                  j@                  de%ej                  j8                     de"e#ej                  j8                  f   dejN                  jP                  de#dej                  j8                  fd„Z)dej                  j@                  dedej                  j8                  de"e#ej                  j8                  f   de$ej                  j8                  df   ddfd„Z*dej                  j@                  de"e#ejN                  jP                  f   de"e#ef   dej                  j@                  fd„Z+dej                  j@                  deddfd„Z,dede"e#ejN                  jP                  f   dej                  j@                  fd„Z-y) é    N)Údefaultdict)ÚOptional)ÚConstantArgumentÚExportedProgramÚModuleCallSignature)Úlegalize_graphÚNodeList)Úerase_nodesÚfuse_as_graphmoduleÚnodeÚreturnc                 ód  — t        | j                  j                  «       «      }t        «       }|D ]}  }|j                  dk(  rŒ|j                  dk(  r|j
                  t        j                  k(  sJ d| › d|› �«       ‚|j                  t        |j                  j                  «       «      «       Œ |S )NÚoutputÚcall_functionz"Expected getitem node as user for z, instead got )	ÚlistÚusersÚkeysÚsetÚopÚtargetÚoperatorÚgetitemÚupdate)r   Ú
node_usersÚgetitem_usersÚusers       úP/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/export/_swap.pyÚ_get_getitem_usersr      s    € Ü�d—j‘j—o‘oÓ'Ó(€JÜ“E€MØò 6ˆØ�7‰7�hÒØð �G‰G�Ò&¨4¯;©;¼(×:JÑ:JÒ+Jð	Kà/°¨v°^ÀDÀ6ÐJó	KØJà×ÑœT $§*¡*§/¡/Ó"3Ó4Õ5ð6ð Ðó    Úcurr_module_nodec                 ó  — t         j                  d| «       t        | j                  j	                  «       «      }t        |«      dk(  sJ dt        |«      › �«       ‚|d   }|j                  dk(  r|j                  t        j                  k(  sJ ‚t        |«      }t        |«      dk7  rt         j                  d||«       yt        t        |«      «      }|j                  dk(  r|j                  t        j                  k(  st         j                  d||«       yt        |j                   d   «      D ]�  \  }}||j                  vr&t         j                  d	| |j                   d   «        y|j                  dk(  r0|j                  t"        j$                  k(  r|j                   d   |k(  rŒyt         j                  d
| |j                   d   «        y t'        «       }t        |«      }|D ]4  }	|j)                  t        |	j                  j	                  «       «      «       Œ6 t        |«      dk7  rt         j                  d||«       yt        t        |«      «      }
|
j                  dk(  st         j                  d||
«       y| f|
_        y)a9  
    We want to try to remove extraneous pytree flatten/unflatten calls between modules
    calls. Instead of having the following:
    graph():
        ...
        %foo : [num_users=1] = call_module[target=foo](args = (%getitem_1, %getitem_2), kwargs = {})
        %tree_flatten_spec : [num_users=1] = call_function[target=torch.fx._pytree.tree_flatten_spec](args = (%foo, %_spec_1), kwargs = {})
        %getitem_4 : [num_users=1] = call_function[target=operator.getitem](args = (%tree_flatten_spec, 0), kwargs = {})
        %tree_unflatten_1 : [num_users=2] = call_function[target=torch.utils._pytree.tree_unflatten](args = ([%getitem_4], %_spec_2), kwargs = {})
        %getitem_5 : [num_users=1] = call_function[target=operator.getitem](args = (%tree_unflatten_1, 0), kwargs = {})
        %getitem_7 : [num_users=0] = call_function[target=operator.getitem](args = (%tree_unflatten_1, 1), kwargs = {})
        %getitem_6 : [num_users=1] = call_function[target=operator.getitem](args = (%getitem_5, 0), kwargs = {})
        %bar : [num_users=1] = call_module[target=bar](args = (%getitem_6,), kwargs = {})
        ...

    We could do the following, if we know that all the outputs of `foo` feed into `bar`:
    graph():
        ...
        %foo : [num_users=1] = call_module[target=foo](args = (%getitem_1, %getitem_2), kwargs = {})
        %bar : [num_users=1] = call_module[target=bar](args = (%getitem_6,), kwargs = {})
        ...

    Currently this optimization only works for the case where all of the outputs
    of `foo` go directly into `bar`, and `bar` has no other inputs.
    z+Trying to remove pytrees for module call %sé   z4Expected only one user for module node, instead got r   r   zaMore than one user found for flatten node, %s: %s. Unable to fuse it with another unflatten call.NzTFlatten node %s's user is not a pytree.tree_unflatten. Instead it is: %s. Passing...z°Module %s's outputs are not all directly used as inputs to the subsequent module. Unable to fuse the connecting flatten/unflatten. The inputs to the subsequent module are: %s. z¬Module %s's outputs are not all directly used in the same order as outputted. Unable to fuse the connecting flatten/unflatten. The inputs to the subsequent module are: %s. zaMore than one user found for unflatten node, %s: %s. Unable to fuse it with another flatten call.Úcall_modulezLUnflatten node %s's user is not a call_module. Instead it is: %s. Passing...)ÚlogÚdebugr   r   r   Úlenr   r   Ú	fx_pytreeÚtree_flatten_specr   ÚnextÚiterÚpytreeÚtree_unflattenÚ	enumerateÚargsr   r   r   r   )r    Úcurr_module_usersÚflatten_nodeÚflatten_getitem_usersÚunflatten_nodeÚiÚargÚunflatten_getitem_getitem_usersÚunflatten_getitem_usersÚunflatten_getitem_userÚnext_module_nodes              r   Ú_try_remove_connecting_pytreesr9   $   sŠ  € ô6 ‡I�IÐ;Ð=MÔNäÐ-×3Ñ3×8Ñ8Ó:Ó;ÐäÐÓ !Ò#ðXà	=¼dÐCTÓ>UÐ=VÐWóXØ#à$ QÑ'€Là�‰˜?Ò*Ø×Ñ¤9×#>Ñ#>Ò>ðð	?ô /¨|Ó<ÐÜ
Ð Ó! QÒ&Ü�	‰	ð=àØ!ô		
ð 	äœ$Ð4Ó5Ó6€Nà×Ñ˜_Ò,Ø×!Ñ!¤V×%:Ñ%:Ò:ä�	‰	ð,àØô		
ð 	ä˜N×/Ñ/°Ñ2Ó3ò ‰ˆˆ3Ø�l×(Ñ(Ñ(Ü�I‰IðSð !Ø×#Ñ# AÑ&ôñ ð �F‰F�oÒ%Ø—
‘
œh×.Ñ.Ò.Ø—‘˜‘˜qÓ ä�I‰Ið.ð !Ø×#Ñ# AÑ&ôñ ð1ô6 '*£eÐ#Ü0°Ó@ÐØ"9ò 
ÐØ'×.Ñ.ÜÐ'×-Ñ-×2Ñ2Ó4Ó5õ	
ð
ô
 Ð*Ó+¨qÒ0Ü�	‰	ð;àØ+ô		
ð 	äœDÐ!@ÓAÓBÐØ×Ñ =Ò0Ü�	‰	ð,àØô		
ð 	ð .Ð/ÐÕr   Úgmc                 ó¤   — | j                   j                  D ]  }|j                  dk(  sŒt        |«       Œ | j                   j	                  «        y)a)  
    Remove extraneous pytree flatten/unflatten calls.

    We try a couple of optimizations here:
        1. Remove pytree flatten/unflatten calls between modules
        2. TODO: Remove module's in_spec + initial unflatten call
        3. TODO: Remove module's out_spec + final flatten call
    r#   N)ÚgraphÚnodesr   r9   Úeliminate_dead_code)r:   r   s     r   Ú_remove_extraneous_pytreesr?   ›   sA   € ð —‘—‘ò 1ˆØ�7‰7�mÓ#Ü*¨4Õ0ð1ð ‡H�H× Ñ Õ"r   Ú	signatureÚnode_name_mapc           	      óò  — g }|j                   D ]n  }t        |t        «      r|j                  €|j	                  d «       Œ1|j
                  |vr|j	                  d «       ŒQ|j	                  ||j
                     «       Œp ddlm}  || ||j                  «      }|j                  j                  dk(  sJ ‚|j                  j                  d   }|j                  �J ‚| j                  j                  t        j                  |df«      }t!        |j                  «      D �	cg c].  }	| j                  j                  t        j                  ||	f«      ‘Œ0 }
}	|j                  j                  d   }|j                  €J ‚| j                  j                  t        j                  |df«      }|j                  D �ci c]/  }|| j                  j                  t        j                  ||f«      “Œ1 }}|
|fS c c}	w c c}w )Nr"   )Ú_generate_unflattené   r   )ÚinputsÚ
isinstancer   ÚvalueÚappendÚnameÚ	unflattenrC   Úin_specÚnum_childrenÚchildren_specsÚcontextr<   r   r   r   Úrange)r:   r@   rA   Útree_unflatten_argsÚinput_rC   r2   Ú	args_specÚ	args_noder3   Ú
args_nodesÚkwargs_specÚkwargs_nodeÚkÚkwargs_nodess                  r   Ú_construct_inputsrY   ¬   sà  € ð
 :<ÐØ×"Ñ"ò 	CˆÜ�fÔ.Ô/°F·L±LÐ4Hð  ×&Ñ& tÕ,Ø�[‰[ Ñ-à×&Ñ& tÕ,à×&Ñ& }°V·[±[Ñ'AÕBð	Cõ /á(¨Ð-@À)×BSÑBSÓT€Nà×Ñ×)Ñ)¨QÒ.Ð.Ð.à×!Ñ!×0Ñ0°Ñ3€IØ×ÑÐ$Ð$Ð$Ø—‘×&Ñ&¤x×'7Ñ'7¸.È!Ð9LÓM€Iô �y×-Ñ-Ó.öàð 	�‰×Ñœx×/Ñ/°)¸Q°Õ@ð€Jð ð
 ×#Ñ#×2Ñ2°1Ñ5€KØ×ÑÐ*Ð*Ð*Ø—(‘(×(Ñ(¬×)9Ñ)9¸NÈAÐ;NÓO€Kð ×$Ñ$öàð 	
ˆ2�8‰8×!Ñ!¤(×"2Ñ"2°[À!Ð4DÓEÑEð€Lð ð �|Ð#Ð#ùòùòs   Ä3G/Æ54G4rT   rX   Úmodule_to_swaprI   c                 óŒ   — ddl m}m}  ||| ||j                  «       | j                  j                  |t        |«      |«      }|S )Nr"   )Ú_assign_attrÚ	_AttrKind)rJ   r\   r]   ÚMODULEr<   r#   Útuple)r:   rT   rX   rZ   rI   r\   r]   Úmodule_nodes           r   Ú_insert_call_modulera   Ö   s>   € ÷ 3á�  T¨9×+;Ñ+;Ô<Ø—(‘(×&Ñ& t¬U°:Ó->ÀÓM€KØÐr   r`   Úorig_outputs.c                 óú   — ddl m}  || ||j                  «      }t        |«      D ]S  \  }}t        j
                  j                  |«      |   j                  }	|j                  |	d¬«       |	||j                  <   ŒU y )Nr"   )Ú_generate_flatten_specT)Úpropagate_meta)
rJ   rd   Úout_specr-   ÚtorchÚfxÚProxyr   Úreplace_all_uses_withrI   )
r:   r@   r`   rA   rb   rd   r0   r3   Úorig_outputÚ	proxy_outs
             r   Ú_deconstruct_outputsrm   ä   ss   € õ 2á)¨"¨k¸9×;MÑ;MÓN€Lä# LÓ1ò 4‰ˆˆ;ä—H‘H—N‘N <Ó0°Ñ3×8Ñ8ˆ	Ø×)Ñ)¨)ÀDÐ)ÔIà*3ˆ�k×&Ñ&Ò'ñ4r   Úmodules_to_swapÚmodule_call_graphc                 óÌ  — t         j                  d«       t         j                  | j                  «       t        | «       t	        t
        «      }| j                  j                  D �ci c]  }|j                  |“Œ }}| j                  j                  D ]R  }|j                  j                  d«      x}sŒ!|j                  «       D ]  \  }}||v sŒ||   j                  |«        ŒR ŒT |j                  «       D ]Ö  \  }	}
	 |	j                  dd«      }t        | |
d|› �«      \  }}}t         j                  d«       t         j                  |j                  «       ||	   }t        | ||«      \  }}t!        | ||||	   |	«      }t#        | ||||«       t%        | |
«       t         j                  d«       t         j                  | j                  «       ŒØ t        | «       t         j                  d«       t         j                  | j                  «       t'        | «       t         j                  d	«       t         j                  | j                  «       | j)                  «        | S c c}w )
NzStarting graph:Únn_module_stackú.Ú_Úfused_zFused subgraph nodes:zSwapped graph:z#Before removing extraneous pytrees:z"After removing extraneous pytrees:)r$   r%   r<   r   r   r   r=   rI   ÚmetaÚgetÚvaluesrH   ÚitemsÚreplacer   rY   ra   rm   r
   r?   Ú	recompile)r:   rn   ro   Ú
partitionsr   rA   rq   Úpathrs   rI   r=   Úsubmod_nameÚsub_gmÚorig_inputsrb   r@   rT   rX   r`   s                      r   Ú_swap_module_helperr€   ÷   s  € ô
 ‡I�IÐÔ Ü‡I�Iˆb�h‰hÔä�2Ôä&1´$Ó&7€Jð %'§H¡H§N¡Nö/Ø ˆ�	‰	�4‰ð/€Mð /ð
 —‘—‘ò ˆØ"Ÿi™iŸm™mÐ,=Ó>Ð>ˆ?Ñ>Ø*×1Ñ1Ó3ò ‘��aØ˜?Ò*Ø˜tÑ$×+Ñ+¨DÔ1Ùñðð "×'Ñ'Ó)ò >‰ˆˆeð(	ðT —l‘l 3¨Ó,ˆÜ,?Ø�˜ ˜}Ð-ó-
Ñ)ˆ�˜\ô 	�	‰	Ð)Ô*Ü�	‰	�&—,‘,Ôà):¸4Ñ)@ˆ	ä#4°R¸ÀMÓ#RÑ ˆ
�LÜ)Ø�
˜L¨/¸$Ñ*?Àó
ˆô 	˜R ¨K¸ÈÔUä�B˜Ôä�	‰	Ð"Ô#Ü�	‰	�"—(‘(Õð}>ô@ �2Ôä‡I�IÐ3Ô4Ü‡I�Iˆb�h‰hÔä˜rÔ"Ü‡I�IÐ2Ô3Ü‡I�Iˆb�h‰hÔà‡L�L„Nà€Iùòo/s   Á'I!c                 óz  — ddl m}m} t        j                  j
                  j                  «       | j
                  _        | j
                  j                  D �cg c]  }|j                  dk(  sŒ|‘Œ }}g }|j                  }|€Âg }|j                  j                  dk(  sJ ‚|j                  j                  d   }|j                  j                  d   }	|j                  t        k(  sJ ‚|	j                  t         k(  sJ ‚t#        |j                  «      D ]  }
|j%                  d|
› �«       Œ |j'                  |	j(                  «       |D ]S  }| j
                  j+                  |d   «      5  |j%                  | j
                  j-                  |«      «       ddd«       ŒU | j
                  j+                  |d   «      5   || t        |«      «      }t/        |«      D ]*  \  }
}d|_	        t0        j2                  |_        ||
f|_        Œ, 	 ddd«       t9        d	„ | j
                  j                  D «       «      }| j
                  j+                  |«      5   || |j6                  d   |j:                  «      }|f|_        ddd«       | j=                  «        yc c}w # 1 sw Y   �Œ[xY w# 1 sw Y   ŒŸxY w# 1 sw Y   Œ8xY w)
a`  
    Given the unlifted module from calling ep.module(), we want to remove the
    pytree processing from the graph module's PyTreeCodeGen and instead make it
    nodes inside of the graph. This allows us to do some optimizations, like
    remove these pytree calls if it is unnecessary, and makes the PyTree part
    more obvious to graph passes.
    r   )Ú_generate_flattenrC   ÚplaceholderNrD   r"   Úarg_r   c              3   ó@   K  — | ]  }|j                   d k(  sŒ|–— Œ y­w)r   N)r   )Ú.0r   s     r   ú	<genexpr>z._fix_input_output_signature.<locals>.<genexpr>‰  s   è ø€ ÒN ¸$¿'¹'ÀXÓ:M”tÑNùs   ‚—)Útorch.export.unflattenr‚   rC   rg   rh   r<   ÚCodeGenÚ_codegenr=   r   Úforward_arg_namesrK   rL   rM   Útyper_   ÚdictrO   rH   ÚextendrN   Úinserting_beforerƒ   r-   r   r   r   r.   r)   rf   rz   )r:   r@   r‚   rC   r   Úold_placeholdersÚnew_placeholdersr‹   Úarg_specÚ
kwarg_specr3   r4   Ú	flat_nodeÚold_placeholderÚoutput_nodeÚunflats                   r   Ú_fix_input_output_signaturer˜   ]  so  € ÷ Nô Ÿ™Ÿ™×.Ñ.Ó0€B‡H�HÔà)+¯©¯©ÖT ¸4¿7¹7ÀmÓ;SšÐTÐÐTàÐØ!×3Ñ3ÐØÐ ØÐØ× Ñ ×-Ñ-°Ò2Ð2Ð2Ø×$Ñ$×3Ñ3°AÑ6ˆØ×&Ñ&×5Ñ5°aÑ8ˆ
Ø�}‰}¤Ò%Ð%Ð%Ø�‰¤$Ò&Ð&Ð&Ü�x×,Ñ,Ó-ò 	1ˆAØ×$Ñ$ t¨A¨3 ZÕ0ð	1à× Ñ  ×!3Ñ!3Ô4à ò ?ˆØ�X‰X×&Ñ&Ð'7¸Ñ':Ó;ñ 	?Ø×#Ñ# B§H¡H×$8Ñ$8¸Ó$=Ô>÷	?ð 	?ð?ð
 
�‰×	"Ñ	"Ð#3°AÑ#6Ó	7ñ 2Ù% b¬%Ð0@Ó*AÓBˆ	Ü"+Ð,<Ó"=ò 	2ÑˆAˆØ!0ˆOÔÜ%-×%5Ñ%5ˆOÔ"Ø$-¨q >ˆOÕ ñ	2÷2ô ÑN¨¯©¯©ÔNÓN€KØ	�‰×	"Ñ	" ;Ó	/ñ %Ù$ R¨×)9Ñ)9¸!Ñ)<¸i×>PÑ>PÓQˆØ"˜9ˆÔ÷%ð ‡L�L…NùòC U÷ 	?ñ 	?ú÷2ð 2ú÷%ð %ús1   ÁJÁ-JÅ(+JÆ;AJ%É*J1ÊJ"	Ê%J.Ê1J:Úepc                 óº  — | j                   D �ci c]&  }|j                  sŒ|j                  |j                  “Œ( }}| j                  «       }d|_        |j
                  j                  «        t        |t        j                  j                  «      sJ ‚t        || j                   d   j                  «       | j                   |_         t        j                  t        |«      j                  |«      |_        t        j                  t        |«      j                   |«      |_        t        |t        j                  j                  «      sJ ‚t#        |||«      }|S c c}w )ab  
    Unlifts the given ExportedProgram into a fx.GraphModule, and then swaps
    previously traced modules with new eager modules specified. Returns a
    fx.GraphModule with a custom forward function.

    Args:
        ep (ExportedProgram): Exported program to modify
        modules_to_swap (Dict[str, torch.nn.Module]): Mapping from module fqn to
            eager module to swap with. The specified module fqn should have also
            been specified in the `preserve_module_call_signature` argument to
            torch.export so that we know how to restore the calling convention
            to this argument.
        run_with_interpreter: Whether or not to run the graph using
            fx.Interpreter. Setting to true will help result in better error
            messages and easier debugging, but it has found to result in a QPS
            drop.
    Fr   )ro   r@   ÚfqnÚmoduleÚvalidate_inputsr<   r>   rF   rg   rh   ÚGraphModuler˜   ÚtypesÚ
MethodTyperŒ   ÚtrainÚevalr€   )r™   rn   Úentryro   r:   s        r   Ú_swap_modulesr¤   ‘  s  € ð* 13×0DÑ0DöØ',ÈÏËˆ�	‰	�5—?‘?Ñ"ðÐð ð 
�‰‹€BØ€BÔØ‡H�H× Ñ Ô"Ü�bœ%Ÿ(™(×.Ñ.Ô/Ð/Ð/Ü  B×$8Ñ$8¸Ñ$;×$EÑ$EÔFà×/Ñ/€BÔÜ×Ñ¤ R£§¡°Ó3€B„HÜ×Ñœt B›xŸ}™}¨bÓ1€B„Gä�bœ%Ÿ(™(×.Ñ.Ô/Ð/Ð/Ü	˜R Ð2CÓ	D€Bà€Iùò#s
   �E¡E).Úloggingr   rŸ   Úcollectionsr   Útypingr   rg   Útorch.fx._pytreerh   Ú_pytreer'   Útorch.utils._pytreeÚutilsr+   Útorch.export.exported_programr   r   r   Útorch.fx.passes.tools_commonr   r	   Ú!torch.fx.passes.utils.fuser_utilsr
   r   Ú	getLoggerÚ__name__r$   ÚNoder   r   r9   rž   r?   r�   Ústrr_   r   rY   ÚnnÚModulera   rm   r€   r˜   r¤   © r   r   ú<module>r¶      sÇ  ðÛ Û Û Ý #Ý ã ß $Ð $ß $Ð $÷ñ ÷
 Bß Nð €g×Ñ˜Ó!€ð˜UŸX™XŸ]™]ð ¨s°5·8±8·=±=Ñ/Aó ðt0°U·X±X·]±]ð t0Àtó t0ðn# 5§8¡8×#7Ñ#7ð #¸Dó #ð"'$Ø�‰×Ñð'$à"ð'$ð ˜˜UŸX™XŸ]™]Ð*Ñ+ð'$ð ˆ4�—‘—‘Ñ  S¨%¯(©(¯-©-Ð%7Ñ 8Ð8Ñ9ó	'$ðTØ�‰×Ñðà�U—X‘X—]‘]Ñ#ðð �s˜EŸH™HŸM™MÐ)Ñ*ðð —H‘H—O‘Oð	ð
 ðð ‡X�X‡]�]óð4Ø�‰×Ñð4à"ð4ð —‘—‘ð4ð ˜˜UŸX™XŸ]™]Ð*Ñ+ð	4ð
 ˜Ÿ™Ÿ™ sÐ*Ñ+ð4ð 
ó4ð&cØ�‰×Ñðcà˜#˜uŸx™xŸ™Ð.Ñ/ðcð ˜CÐ!4Ð4Ñ5ðcð ‡X�X×Ñó	cðL1Ø�‰×Ñð1Ø)<ð1à	ó1ðh%Øð%Ø*.¨s°E·H±H·O±OÐ/CÑ*Dð%à
‡X�X×Ñô%r   