Ë
    M²j„  ã                   ól  — 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
Z
d dlZd dlmc mZ d dlmZ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 d d
lmZmZ d dl m!Z!m"Z" d dl#m$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/ dej`                  dej`                  de1fd„Z2dej`                  de3fd„Z4de3e5   fd„Z6de3e5   fd„Z7de3e5   de3ejp                     fd„Z9ejt                  jv                  d„ «       Z<d„ Z=d ej|                  j~                  d!ee5dz     de@eAe5ej|                  j„                  f   eAe5ej|                  j„                  f   f   fd"„ZCd ej|                  j~                  d#ee5dz     d$eAe5ej|                  j„                  f   d%eAe5ej|                  j„                  f   ddf
d&„ZD	 dDdej`                  d'ej`                  dz  d(e3e5   dz  defd)„ZE	 dDd ej|                  j~                  d!ee5dz     d#ee5dz     dej`                  d'ej`                  dz  d(e3e5   dz  fd*„ZFd+ej|                  j~                  d,e-d-eAe5e	f   d.eAe5e	f   ddf
d/„ZG G d0„ d1eH«      ZI G d2„ d3ej|                  j~                  eI¬4«      ZJd5ej|                  j~                  d6e,deJfd7„ZKd8„ ZLd9e5d:e3e	   fd;„ZMd<e3ej|                  j„                     d=eAe
jœ                  e&f   d>e3ejp                     fd?„ZOd@„ ZP	 dEd6e,dej|                  j~                  fdA„ZQ G dB„ dCej¤                  j¦                  «      ZTy)Fé    N)ÚSequence)Úchain)ÚAny)Ú,_enter_enable_graph_inputs_of_type_nn_moduleÚ+_exit_enable_graph_inputs_of_type_nn_moduleÚ#_get_graph_inputs_of_type_nn_module)Ú_convert_range_to_int)Ú"_check_input_constraints_for_graph)Ú_assign_attrÚ	_AttrKind)Ú!_pytree_subclasses_that_lose_info)Ú_PyTreeCodeGenÚ_PyTreeInfo)Ú
NodeSourceÚNodeSourceAction)Ú	try_solve)ÚValueRangesé   )Ú_remove_effect_tokens)Úreorder_kwargs)ÚExportedProgramÚExportGraphSignatureÚ	InputKindÚ
OutputKindÚselfÚotherÚreturnc                 ó*   ‡‡— d„ Šˆˆfd„Š ‰| |«      S )z§
    Refinement of TreeSpec.__eq__ where, e.g., torch.Size(...) matches tuple(...).
    See _pytree_subclasses_that_lose_info in proxy_tensor.py for more details.
    c                 ó@   — t        t        j                  | | «      «      S ©N)Ústrr   Úget)Úts    úS/var/www/html/ia-enhanced/venv/lib/python3.12/site-packages/torch/export/_unlift.pyÚ_normalize_typez eq_spec.<locals>._normalize_type.   s   € ÜÔ4×8Ñ8¸¸AÓ>Ó?Ð?ó    c                 óÖ  •— | |u ry ‰| j                   «       ‰|j                   «      k7  ry| j                   t        u r>|j                   t        u r,t        | j                  «      t        |j                  «      k7  ry| j                  |j                  k7  ry| j                  |j                  k7  ryt        ˆfd„t        | j                  «       |j                  «       «      D «       «      S )NTFc              3   ó6   •K  — | ]  \  }} ‰||«      –— Œ y ­wr    © )Ú.0ÚaÚbÚ_match_normalized_structures      €r$   ú	<genexpr>z?eq_spec.<locals>._match_normalized_structure.<locals>.<genexpr>>   s$   øè ø€ ò 
á��1ñ (¨¨1×-ñ
ùs   ƒ)ÚtypeÚdictÚsetÚcontextÚnum_childrenÚallÚzipÚchildren)r+   r,   r-   r%   s     €€r$   r-   z,eq_spec.<locals>._match_normalized_structure1   s­   ø€ Ø�‰6ØÙ˜1Ÿ6™6Ó"¡o°a·f±fÓ&=Ò=ØØ�6‰6”T‰>˜aŸf™f¬™nä�1—9‘9‹~¤ Q§Y¡Y£Ò/ØØ�Y‰Y˜!Ÿ)™)Ò#ØØ�>‰>˜QŸ^™^Ò+ØÜó 
ä˜AŸJ™J›L¨!¯*©*«,Ó7ô
ó 
ð 	
r&   r)   )r   r   r-   r%   s     @@r$   Úeq_specr7   (   s   ù€ ò@õ
ñ$ ' t¨UÓ3Ð3r&   Úin_specc                 óŽ   — t        ||«      }t        j                  | |f«      \  }}t        ||«      st	        d|› d|› d�«      ‚|S )Nz>Trying to flatten user inputs with exported input tree spec: 
z-
but actually got inputs with tree spec of: 
zr.
Please check that the inputs have the same number and type of args and kwargs as the ones you used when tracing.)r   ÚpytreeÚtree_flatten_with_pathr7   Ú
ValueError)ÚargsÚkwargsr8   Úreordered_kwargsÚflat_args_with_pathÚreceived_specs         r$   Ú_check_inputs_matchrB   F   sm   € Ü% f¨gÓ6ÐÜ)/×)FÑ)FØ	ÐÐ ó*Ñ&Ð˜ô �= 'Ô*ÜØMØˆið <àˆoð AðAó
ð 	
ð Ðr&   Úep_guards_codec                 óö   — i }t        |«      D ]$  \  }}dt        j                  |«      › �|d|› d�<   Œ& g }| D ]=  }|j                  «       D ]  \  }}|j	                  ||«      }Œ |j                  |«       Œ? |S )NÚLúL['flat_args'][ú])Ú	enumerater:   ÚkeystrÚitemsÚreplaceÚappend)	rC   Úinput_pathsÚname_mappingÚidxÚpathÚnew_guards_codeÚguardÚold_nameÚnew_names	            r$   Ú_force_ep_signature_matchrU   Y   s    € ð €LÜ˜{Ó+ò K‰	ˆˆTØ34´V·]±]À4Ó5HÐ4IÐ1Jˆ� s e¨1Ð-Ò.ðKð €OØò &ˆØ".×"4Ñ"4Ó"6ò 	6ÑˆH�hØ—M‘M (¨HÓ5‰Eð	6à×Ñ˜uÕ%ð&ð
 Ðr&   c                 ót  — ddl }t        «       }| D ]#  }|j                  |j                  d|«      «       Œ% t        «       }|j                  D ]#  }|j                  |j                  d|«      «       Œ% | }|D ]9  }||v sŒ|\  }	}
|D �cg c]"  }|j                  d|	› d|
› d�d|	› d|
› d	�«      ‘Œ$ }}Œ; |S c c}w )
aP  
    The signature of the originally exported module may not match
    the signature of the unlifted graph module extracted from the
    exported program. The guards code extracted from the exported
    program is based on the former, but the generated guards fn is
    based on the latter; thus we need to reconcile any such diff.
    r   NzL\[\'([^\']+)\'\]\[([0-9]+)\]z(.+)_([0-9]+)zL['z'][rG   Ú_z'])Úrer1   ÚupdateÚfindallÚ
parametersrK   )rC   Ú	signaturerX   Úorig_arg_namesÚgÚsig_arg_namesÚnrQ   ÚmatchÚbaserO   s              r$   Ú_force_gm_signature_matchrc   p   sï   € ó ô “U€NØò Oˆà×Ñ˜bŸj™jÐ)IÈ1ÓMÕNðOô “E€MØ×!Ñ!ò >ˆà×Ñ˜RŸZ™ZÐ(8¸!Ó<Õ=ð>ð
 %€OØò ˆØ�MÒ!Ø‰IˆD�#ð )öàð —	‘	˜C ˜v S¨¨¨QÐ/°3°t°f¸A¸c¸UÀ"Ð1EÕFðˆOñ ðð Ðùòs   Â'B5Úguards_codeÚpaths_of_placeholdersc                 óØ  — ddl }ddlm} g }g }| D ]Å  }||}}t        |«      D ]  \  }	}
|j	                  dt        j                  |
«      z   d|	› d�«      }|j	                  dt        j                  |
«      z   |
d   j                  t        j                  |
dd «      z   «      }Œ� |j                  |«       |j                  |j	                  dd	«      «       ŒÇ d
}t        ||«      D ]3  \  }}|j                  |j                  |d¬«      «      }|d|› d|› d�z  }Œ5 |dz  }i |¥}t        ||«       t        «       }t        j                  j!                  |d   «      |_        d|_        |S )ah  
    Generates Python code given guards code and paths of placeholders.
    We assume that, based on source information,
    - the tracer generates the guards code
    - the input spec generates the paths of placeholders.

    Example:

    Suppose we are given the guards code "L['z']['k'].size()[1] == 3"
    and we are given that ['z']['k'] is the path of placeholder #2.
    Then we will generate:
    ```
    torch._assert(
        args[2].size()[0] == 3,
        "Guard failed: z['k'].size()[0] == 3",
    )
    ```

    FAQ: Why do we generate code based on (flattened) args instead of
    the original (unflattened) inputs? Because this would require
    inserting an additional pytree.unflatten call in our graph.

    FAQ: Why do we not emit RuntimeError on guard failure as we used to?
    Because it is inconvenient :/, get used to AssertionError instead.
    r   N)ÚSYMPY_INTERPrE   zargs[rG   r   ú
Ú z
def _(*args):
Úeval)Úmodez  torch._assert(z, "Guard failed: z")
z	  return
rW   T)ÚastÚ%torch.fx.experimental.symbolic_shapesrg   rH   rK   r:   rI   ÚkeyrL   r5   ÚunparseÚparseÚexecÚGuardsFnÚtorchÚ_dynamoÚdont_skip_tracingÚforwardÚ
_is_impure)rd   re   rl   rg   Úactual_guards_codeÚshadow_guards_codeÚcr+   ÚsrO   rP   Úcode_strÚactualÚshadowÚ_shadowÚ	namespaceÚ	guards_fns                    r$   Ú_convert_guards_code_to_fnr‚   “   s…  € ó< åBàÐØÐØò 7ˆØ�!ˆ1ˆÜ"Ð#8Ó9ò 	‰IˆC�à—	‘	˜#¤§¡¨dÓ 3Ñ3°u¸S¸EÀ°^ÓDˆAà—	‘	Ø”f—m‘m DÓ)Ñ)Ø�Q‘—‘œfŸm™m¨D°°¨HÓ5Ñ5ó‰Að		ð 	×!Ñ! !Ô$Ø×!Ñ! !§)¡)¨D°"Ó"5Õ6ð7ð #€HÜÐ0Ð2DÓEò N‰ˆ�ð —+‘+˜cŸi™i¨°V˜iÓ<Ó=ˆàÐ& v hÐ.?À¸yÈÐMÑM‰ðNð �Ñ€Hð !�<Ð €IÜˆ�9Ôô “
€IÜŸ™×7Ñ7¸	À#¹ÓG€IÔØ€IÔØÐr&   c                 ó”   — t        ||| j                  «      }t        | j                  j	                  d¬«      || j
                  «       y )NÚplaceholder©Úop)rB   Ú_in_specr
   ÚgraphÚ
find_nodesÚrange_constraints)r   r=   r>   r@   s       r$   Ú#_check_input_constraints_for_moduler‹   Þ   s>   € ä-¨d°F¸D¿M¹MÓJÐÜ&Ø�
‰
×Ñ ÐÓ/ØØ×Ñõr&   c                 ó¾   — | j                   sy t        | d«      rt        ||| j                  «       y t        j
                  j                  «       st        | ||«       y y )NÚ
_guards_fn)Úvalidate_inputsÚhasattrrB   r‡   rs   ÚcompilerÚis_dynamo_compilingr‹   )r   r=   r>   s      r$   Ú!_check_input_constraints_pre_hookr’   è   sP   € à×ÒØô
 ˆt�\Ô"Ü˜D &¨$¯-©-Ô8Øô
 �>‰>×-Ñ-Ô/Ü+¨D°$¸Õ?ð 0r&   ÚgmÚlifted_inputsc                 óV  — i }i }| j                   j                  D �cg c]  }|j                  dk(  sŒ|‘Œ }}t        |«      t        |«      k7  r$t	        dt        |«      › dt        |«      › d�«      ‚t        ||«      D �]  \  }}|€|||j                  <   Œ| j                   j                  |«      5  t        j                  «       5  t        j                  d«       | j                   j                  |«      }ddd«       |j                  «       |j                  }	| j                   j                  |«       |	|_        t        |dt         j"                  t         j$                  g«      g|j                  d<   |||<   ddd«       �Œ	 ||fS c c}w # 1 sw Y   ŒšxY w# 1 sw Y   �Œ)xY w)	z_
    Unlift inputs referring to params/buffers/constants as getattr nodes in the
    graph
    r„   zNumber of lifted inputs (z$) does not match placeholder nodes (ú)NÚignoreú!ExportedProgram.module().unlift()Ú	from_node)rˆ   Únodesr†   ÚlenÚAssertionErrorr5   ÚnameÚinserting_afterÚwarningsÚcatch_warningsÚsimplefilterÚget_attrÚreplace_all_uses_withÚmetaÚ
erase_noder   r   ÚCREATEÚREPLACE)
r“   r”   Úunlifted_name_to_nodeÚinput_name_to_nodeÚnodeÚplaceholder_nodesÚ
input_nodeÚlifted_nodeÚgetattr_nodeÚmetadatas
             r$   Ú_unlift_inputs_as_getattrr°   û   s·  € ð ÐØÐà*,¯(©(¯.©.ÖU $¸D¿G¹GÀ}Ó<TšÐUÐÐUÜ
ˆ=ÓœSÐ!2Ó3Ò3ÜØ'¬¨MÓ(:Ð';ð <"Ü"%Ð&7Ó"8Ð!9¸ð<ó
ð 	
ô $'Ð'8¸-Ó#Hó BÑˆ
�KØÐØ2<Ð˜zŸ™Ò/ð —‘×)Ñ)¨*Ó5ñ Bô ×,Ñ,Ó.ñ BÜ×)Ñ)¨(Ô3Ø#%§8¡8×#4Ñ#4°[Ó#A�L÷Bð ×0Ñ0°Ô>Ø%Ÿ?™?�Ø—‘×#Ñ# JÔ/Ø$,�Ô!äØ"Ø;Ü)×0Ñ0Ô2B×2JÑ2JÐKóð2�×!Ñ! +Ñ.ð 6BÐ% kÑ2÷%Bñ BðBð2 !Ð"4Ð4Ð4ùò? V÷Bð Bú÷	Bñ Bús/   �F²FÂ3FÃ1FÃ9BFÆFÆFÆF(	Úmutated_outputsr¨   r©   c                 ó†  ‡— | j                   j                  «       }t        j                  |j                  «      d   }t        |«      t        |«      k7  r$t        dt        |«      › dt        |«      › d�«      ‚g }i Št        ||«      D ]¯  \  }}|€|j                  |«       Œ||v r||   }	n||v r||   }	nt        d|› d�«      ‚| j                   j                  |«      5  | j                   j                  t        j                  j                  j                  j                   |	|f«      }
|
‰|<   ddd«       Œ± t#        ˆfd„|D «       «      }| j                   j                  |«      5  | j                   j%                  |«      }|j'                  |«       | j                   j)                  |«       |j*                  |_        |j,                  j/                  |j,                  «       t1        |d	t2        j4                  t2        j6                  g«      g|j,                  d
<   ddd«       y# 1 sw Y   �Œ«xY w# 1 sw Y   yxY w)zt
    Find the all the buffers and inputs that were mutated and insert copy_
    operators to reflect mutations.
    r   zNumber of outputs (z") does not match mutated outputs (r–   NzCould not find z  in either buffer or input nodesc              3   óB   •K  — | ]  }‰j                  ||«      –— Œ y ­wr    )r"   )r*   rª   Úreturn_nodes_to_copys     €r$   r.   z-_insert_copy_for_mutations.<locals>.<genexpr>P  s$   øè ø€ ò Ø15Ð× Ñ   t×,ñùs   ƒr˜   r™   )rˆ   Úoutput_noder:   Útree_flattenr=   r›   rœ   r5   rL   ÚRuntimeErrorÚinserting_beforeÚcall_functionrs   ÚopsÚatenÚcopy_ÚdefaultÚtupleÚoutputr£   r¥   r�   r¤   rY   r   r   r¦   r§   )r“   r±   r¨   r©   rµ   ÚoutputsÚuser_output_nodesÚreturn_nodeÚmutated_node_nameÚmutated_nodeÚ	copy_nodeÚoutput_argsÚ
new_outputr´   s                @r$   Ú_insert_copy_for_mutationsrÈ   (  s5  ø€ ð —(‘(×&Ñ&Ó(€KÜ×!Ñ! +×"2Ñ"2Ó3°AÑ6€GÜ
ˆ7ƒ|”s˜?Ó+Ò+ÜØ!¤# g£, ð 0 Ü # OÓ 4Ð5°Qð8ó
ð 	
ð
 ÐØÐÜ*-¨g°Ó*Gò :Ñ&ˆÐ&ØÐ$Ø×$Ñ$ [Ô1ØàÐ 5Ñ5Ø0Ð1BÑC‰LØÐ"4Ñ4Ø-Ð.?Ñ@‰LäØ!Ð"3Ð!4Ð4TÐUóð ð �X‰X×&Ñ& {Ó3ñ 	:ØŸ™×.Ñ.Ü—	‘	—‘×$Ñ$×,Ñ,¨|¸[Ð.IóˆIð 1:Ð  Ñ-÷		:ð 	:ð:ô( ó Ø9Jôó €Kð 
�‰×	"Ñ	" ;Ó	/ñ 
à—X‘X—_‘_ [Ó1ˆ
Ø×)Ñ)¨*Ô5Ø
�‰×Ñ˜KÔ(Ø%×*Ñ*ˆ
ŒØ�‰×Ñ˜{×/Ñ/Ô0äØØ3Ü!×(Ñ(Ô*:×*BÑ*BÐCóð(
ˆ
�‰˜Ñ$÷
ð 
÷	:ñ 	:ú÷
ð 
ús   Ã!AH*Å*B7H7È*H4	È7I Úout_specÚforward_arg_namesc                 ó  — |r|}nç| j                   t        u r°| j                  dk(  r¡| j                  d«      j                   t        u r€| j                  d«      j                   t        u r_t        | j                  d«      j                  «      D �cg c]  }d|› �‘Œ	 }}|j                  | j                  d«      j                  «       n%t        | j                  «      D �cg c]  }d|› �‘Œ	 }}t        t        || |«      «      S c c}w c c}w )zK
    Create the codegen for the graph module based on the in/out specs
    é   r   r   Úarg_)
r/   r¾   r3   Úchildr0   ÚrangeÚextendr2   r   r   )r8   rÉ   rÊ   ÚnamesÚis        r$   Ú_get_codegenrÓ   c  sì   € ñ Ø!‰à�‰œÑØ× Ñ  AÒ%Ø�M‰M˜!Ó×!Ñ!¤UÑ*Ø�M‰M˜!Ó×!Ñ!¤TÑ)ô &+¨7¯=©=¸Ó+;×+HÑ+HÓ%IÖJ �4˜�s’ÐJˆÐJà�‰�W—]‘] 1Ó%×-Ñ-Õ.ä%*¨7×+?Ñ+?Ó%@ÖA �4˜�s’ÐAˆÐAäÜØØØó	
óð ùò Kùò Bs   ÂDÃDc                 óÌ   — t        | |«      \  }}t        | |||«       t        |||«      | j                  _        | j                  j                  «        | j                  «        | S )a  
    Args:
        lifted_inputs: A list matching the graph module's input nodes. For
        an input node that is referring to a lifted parameter/buffer, this
        list will contain the fqn the corresponding attribute. Otherwise, this
        list will contain None. This is used to unlift the lifted parameters as
        get_attr nodes.

        mutated_outputs: A list matching the graph module's output nodes. For
        an output node that is referring to a mutated buffer or user input, this
        list will contain the name of the corresponding buffer or user input
        that needs to be mutated. Otherwise, this list will contain None. This
        is used to re-insert an inplace copy_ operator to copy the mutated
        values back to the original node.
    )r°   rÈ   rÓ   rˆ   Ú_codegenÚlintÚ	recompile)r“   r”   r±   r8   rÉ   rÊ   r¨   r©   s           r$   Ú_unliftrØ   ƒ  sc   € ô. 1JØ
ˆMó1Ñ-ÐÐ-ô Ø
ˆOÐ2Ð4Fôô % W¨hÐ8IÓJ€B‡H�HÔØ‡H�H‡M�M„OØ‡L�L„NØ€Ir&   Únew_gmÚgraph_signatureÚ
state_dictÚ	constantsc                 ó¦  — t        |j                  «      }|j                  D ]3  }||v rd}||   }nd}||   }t        || |t        j
                  |¬«       Œ5 |j                  D ]$  }||   }t        || |t        j                  ¬«       Œ& t        |j                  |j                  «      D ]$  }||   }t        || |t        j                  ¬«       Œ& y )NFT©Ú	attr_kindÚ
persistent©rß   )r1   Únon_persistent_buffersÚbuffersr   r   ÚBUFFERr[   Ú	PARAMETERr   Úlifted_custom_objsÚlifted_tensor_constantsÚCONSTANT)rÙ   rÚ   rÛ   rÜ   râ   r�   rà   Úvalues           r$   Ú_register_attrs_to_new_gmrê   ¦  sð   € ô ! ×!GÑ!GÓHÐØ×'Ñ'ò 	
ˆØÐ)Ñ)ØˆJØ˜d‘O‰EàˆJØ˜tÑ$ˆEÜØ�6˜4¬9×+;Ñ+;È
ö	
ð	
ð  ×*Ñ*ò 
ˆØ˜4Ñ ˆÜØØØÜ×)Ñ)ö		
ð
ô Ø×*Ñ*¨O×,SÑ,Sóò 	
ˆð ˜$‘ˆÜØØØÜ×(Ñ(ö		
ñ		
r&   c                   ó*   ‡ — e Zd ZdZd„ Zdˆ fd„	Zˆ xZS )Ú_StatefulGraphModuleFactoryzO
    Metaclass that ensures a private constructor for _StatefulGraphModule
    c                 óL   — t        | j                  › d| j                  › d�«      ‚)Nú.z has no public constructor. )Ú	TypeErrorÚ
__module__Ú__qualname__)Úclsr=   r>   s      r$   Ú__call__z$_StatefulGraphModuleFactory.__call__Ô  s,   € ÜØ�~‰~Ð˜a × 0Ñ 0Ð1Ð1MÐNó
ð 	
r&   c                 ó(   •— t         ‰| �  |||¬«      S )N©rŠ   )Úsuperró   )rò   Úrootrˆ   rŠ   Ú	__class__s       €r$   Ú_createz#_StatefulGraphModuleFactory._createÙ  s#   ø€ Ü‰wÑØØØ/ð  ó 
ð 	
r&   r    )Ú__name__rð   rñ   Ú__doc__ró   rù   Ú__classcell__©rø   s   @r$   rì   rì   Ï  s   ø„ ñò
÷

ñ 
r&   rì   c                   ó    ‡ — e Zd Zdˆ fd„	Zˆ xZS )Ú_StatefulGraphModulec                 óJ   •— t         ‰| �  ||«       |xs g | _        d| _        y )NT)rö   Ú__init__rŠ   rŽ   )r   r÷   rˆ   rŠ   rø   s       €r$   r  z_StatefulGraphModule.__init__â  s'   ø€ Ü‰Ñ˜˜uÔ%à!2Ò!8°bˆÔØ#ˆÕr&   r    )rú   rð   rñ   r  rü   rý   s   @r$   rÿ   rÿ   á  s   ø„ ÷$ñ $r&   rÿ   )Ú	metaclassÚplain_graph_moduleÚepc                 óÆ  ‡— t         j                  | | j                  |¬«      }t        |j                  «      Š|j                  ˆfd„«       |j                  t        d¬«       |j                  ˆfd„d¬«       i }|j                  j                  D ]¸  }|j                  |«      }|j                  r2t        j                  d|› d�d	¬
«       |j                  «       }|||<   |}|j                  d«      �^ }}	t         j"                  j$                  j'                  ||«      }
t)        |
|	«       t+        |||t,        j.                  ¬«       Œº |j0                  j3                  «       D ]¯  \  }}t         j"                  j$                  j5                  ||«      rŒ1t7        |t         j8                  «      rH|j                  r<t        j                  d|› d�d	¬
«       ||v r||   }n|j                  «       }|||<   |}t+        |||t,        j.                  ¬«       Œ± |j                  j:                  D ]/  }t+        | j                  |«      ||t,        j<                  d¬«       Œ1 |S )Nrõ   c                  ó   •— t        ‰«      S r    )r   ©r=   r>   Úmodule_typess     €r$   ú<lambda>z/_create_stateful_graph_module.<locals>.<lambda>ö  s   ø€ Ô LØó!
€ r&   T)Úwith_kwargsc                  ó   •— t        ‰«      S r    )r   r  s     €r$   r	  z/_create_stateful_graph_module.<locals>.<lambda>ÿ  s   ø€ Ô KØó!
€ r&   )Úalways_callzA model attribute `z°` requires gradient. but it's not properly registered as a parameter. torch.export will detach it and treat it as a constant tensor but please register it as parameter instead.rÌ   )Ú
stacklevelrî   rá   z¯` requires gradient but it's not properly registered as a parameter. torch.export will detach it and treat it as a constant tensor but please register it as parameter instead.FrÞ   )rÿ   rù   rˆ   r   Úexample_inputsÚregister_forward_pre_hookr’   Úregister_forward_hookrÚ   rç   Ú
get_bufferÚrequires_gradrŸ   ÚwarnÚdetachÚrsplitrs   ÚfxÚgraph_moduleÚ_get_attr_via_attr_listÚdelattrr   r   rè   rÜ   rJ   Ú	_has_attrÚ
isinstanceÚTensorrâ   rä   )r  rŠ   r  Ústateful_gmÚ"original_tensor_to_detached_tensorÚconstant_fqnÚbufferÚdetached_bufferÚprefixÚfieldÚsubmodÚ
const_nameré   Údetached_valuer  s                 @r$   Ú_create_stateful_graph_moduler'  é  sf  ø€ ô
 '×.Ñ.ØØ× Ñ Ø+ð /ó €Kô 7°r×7HÑ7HÓI€LØ×)Ñ)ó	
ôð
 ×)Ñ)Ü)°tð *ô ð ×%Ñ%ó	
ð ð	 &ô ð *,Ð&ð ×*Ñ*×BÑBò Vˆð ×'Ñ'¨Ó5ˆØ×ÒÜ�M‰MØ% l ^ð 4?ð @ð õð %Ÿm™m›oˆOØ9HÐ.¨vÑ6Ø$ˆFØ%×,Ñ,¨SÓ1‰ˆ�Ü—‘×&Ñ&×>Ñ>¸{ÈFÓSˆÜ�˜ÔÜ�V˜[¨,Ä)×BTÑBTÖUð+Vð0  Ÿ\™\×/Ñ/Ó1ò Ñˆ
�EÜ�x‰x×$Ñ$×.Ñ.¨{¸JÕGÜ˜%¤§¡Ô.Ø×&Ò&Ü—M‘MØ-¨j¨\ð :Gð Hð $%õð Ð BÑBØ BÀ5Ñ I™à).¯©«˜ØDRÐ:¸5ÑAØ .˜ÜØØØÜ#×,Ñ,ö	ð#ð6 ×$Ñ$×;Ñ;ò 
ˆÜØ×)Ñ)¨&Ó1ØØÜ×&Ñ&Øö	
ð
ð Ðr&   c                 óÈ   — | \  }} |j                   |i |¤Ž}|j                  «        |j                  }t        j                  |«      }|D ��cg c]  \  }}|‘Œ	 c}}S c c}}w )zë
    Generate paths of placeholders, needed for generating the guards function.

    NOTE: Here we make use of the example inputs used for export as well as
    the signature of the unlifted graph module (not preserved by export).
    )ÚbindÚapply_defaultsÚ	argumentsr:   Útree_leaves_with_path)	r  r\   r=   r>   ÚbindedÚctxÚflat_example_inputs_with_pathsrP   rW   s	            r$   Ú_get_input_pathsr0  P  sb   € ð "�L€Dˆ&ØˆY�^‰^˜TÐ, VÑ,€FØ
×ÑÔØ
×
Ñ
€CÜ%+×%AÑ%AÀ#Ó%FÐ"Ø >×?‘W�T˜1ŠDÓ?Ð?ùÓ?s   ÁAÚ
result_strÚflat_input_pathsc                 óÆ   — i }t        |«      D ]$  \  }}dt        j                  |«      › �|d|› d�<   Œ& | }|j                  «       D ]  \  }}|j	                  ||«      }Œ |S )zz
    Given user specified input paths, maybe fix up the guard string
    to reflect user path instead of tracer path.
    rE   rF   rG   )rH   r:   rI   rJ   rK   )r1  r2  rN   rO   rP   rK   rn   Úvals           r$   Ú_replace_sourcesr5  `  s€   € ð
 €LÜÐ/Ó0ò K‰	ˆˆTØ34´V·]±]À4Ó5HÐ4IÐ1Jˆ� s e¨1Ð-Ò.ðKð €GØ ×&Ñ&Ó(ò ,‰ˆˆSØ—/‘/ # sÓ+‰ð,à€Nr&   ÚplaceholdersrŠ   Úpaths_for_placeholdersc                 ón  ‡‡‡‡— g Šg Ši Šˆˆˆˆfd„}t        | |«      D �]  \  }}dt        j                  |«      z   }|j                  d   }t	        |t
        «      r‰j                  |› d|› �«       t	        |t        «      rh|t        j                  k(  r‰j                  |› d�«       ŒŒ|t        j                   k(  r‰j                  |› d�«       Œµ‰j                  |› d|› �«       ŒÌt	        |t        «      r‰j                  |› d|› d�«       Œôt	        |t        j                  «      r7|j                  j                  ‰v r ||j                  j                  |«       �ŒEt	        |t        j                  «      s�Œat!        |j"                  «      D ]œ  \  }}	dt        j                  |«      z   d	|› d
�z   }t	        |	t
        «      r‰j                  |› d|	› �«       ŒLt	        |	t        j                  «      sŒg|	j                  j                  ‰v sŒ€ ||	j                  j                  |«       Œž �Œ i }
t        j$                  j&                  j(                  j+                  «       }‰D ]Å  \  }}t-        t/        |j0                  «      «      }|‰v rŒ)||
v rY|j3                  |
«      }‰j                  |j5                  t7        j8                  |t7        j:                  |«      «      «      «       Œ†t=        t7        j8                  |t7        j:                  |«      «      |«      }|€Œ¼|d   }||
|<   ŒÇ ‰S )aX  
    Guards generated by the tracer include conditions observed in code, but
    but do not include some additional checks we typically do in export.
    For example, when dynamic shapes get specialized, are specified to be
    within a range, or are specified to be in some equational relation,
    corresponding input invalidation is done within a pre_hook, specifically,
    `_check_input_constraints_for_graph`.

    Here we generate guards corresponding to the checks that happen in
    `_check_input_constraints_for_graph`, and add them to the guards already
    generated by the tracer. In the future, it may be worthwhile to separate
    them so that we can allow clients to turn off one but not the other.
    (Looking at you, AOTI.)

    NOTE: We should eventually reconcile this logic with `build_guards` that
    is used by AOT Precompile.
    c                 óR  •— t        | j                  «      dk(  r‰j                  || f«       | ‰v r‰|    }‰j                  |› d|› �«       y |‰| <   t        ‰|    «      \  }}|dkD  r‰j                  |› d|› �«       |t        j
                  k  r‰j                  |› d|› �«       y y )Nr   ú == rÌ   z >= z <= )r›   Úfree_symbolsrL   r	   ÚmathÚinf)	ÚexprÚsrcÚorig_srcÚmin_valÚmax_valÚdeferred_expressionsrQ   rŠ   Úsourcess	        €€€€r$   Úhandle_symintz2_get_input_guards_for_graph.<locals>.handle_symintŠ  s½   ø€ Üˆt× Ñ Ó! QÒ&ð !×'Ñ'¨¨d¨Ô4Ø�7‰?ð ˜t‘}ˆHØ×"Ñ" c U¨$¨x¨jÐ#9Õ:àˆG�D‰Mä4Ð5FÀtÑ5LÓMÑˆG�WØ˜Š{Ø×&Ñ&¨#¨¨d°7°)Ð'<Ô=ØœŸ™Ò!Ø×&Ñ&¨#¨¨d°7°)Ð'<Õ=ð "r&   rE   r4  r:  z == math.infz == -math.infz == 'ú'z.size()[rG   r   )r5   r:   rI   r¤   r  ÚintrL   Úfloatr<  r=  r!   rs   ÚSymIntrª   r>  r  rH   ÚshapeÚutilsÚ_sympyÚprintersÚPythonPrinterÚnextÚiterr;  ÚsubsÚdoprintÚsympyÚEqÚSymbolr   )r6  rŠ   r7  rE  r„   rP   r?  r¤   rÒ   ÚdimÚunification_mapÚ
py_printerr>  ÚsymbolÚsubstitutionÚsolutionÚ
definitionrC  rQ   rD  s    `               @@@r$   Ú_get_input_guards_for_graphr]  o  sÂ  û€ ð. ÐØ€OØ%'€G÷>ô* ! Ð/EÓFó 6Ñˆ�TØ”F—M‘M $Ó'Ñ'ˆØ×Ñ Ñ&ˆä�dœCÔ Ø×"Ñ" c U¨$¨t¨fÐ#5Ô6Ü�dœEÔ"Ø”t—x‘xÒØ×&Ñ&¨#¨¨lÐ';Õ<Øœ$Ÿ(™(˜Ò"Ø×&Ñ&¨#¨¨mÐ'<Õ=à×&Ñ&¨#¨¨d°4°&Ð'9Õ:Ü˜œcÔ"Ø×"Ñ" c U¨%°¨v°QÐ#7Õ8ä˜œeŸl™lÔ+°·	±	·±ÐBSÑ0SÙ˜$Ÿ)™)Ÿ.™.¨#Ö.Ü˜œeŸl™lÖ+Ü# D§J¡JÓ/ò 	6‘��3ØœFŸM™M¨$Ó/Ñ/°H¸Q¸C¸q°/ÑA�Ü˜c¤3Ô'à#×*Ñ*¨c¨U°$°s°eÐ+<Õ=ä˜s¤E§L¡LÕ1°c·h±h·m±mÐGXÒ6Xñ " #§(¡(§-¡-°Õ5ò	6ð'6ð< 79€OÜ—‘×#Ñ#×,Ñ,×:Ñ:Ó<€Jð *ò 5‰	ˆˆTä”d˜4×,Ñ,Ó-Ó.ˆØ�WÑð ð �_Ñ$ð  Ÿ9™9 _Ó5ˆLØ×"Ñ"Ø×"Ñ"¤5§8¡8¨L¼%¿,¹,ÀsÓ:KÓ#LÓMõô !¤§¡¨$´·±¸SÓ0AÓ!BÀFÓKˆHØÑ#Ø% a™[�
Ø*4� Ò'ð15ð4 Ðr&   c                  ó‚   ‡— g d¢} t        j                  «       Š‰�$t        ˆfd„| D «       «      ry‰j                  Š‰�Œ$y)N)Ú
executorchÚmodaiÚon_device_aiÚtorchaoc              3   óN   •K  — | ]  }|‰j                   j                  v –— Œ y ­wr    )Úf_codeÚco_filename)r*   rP   Úframes     €r$   r.   z,_ok_to_generate_guards_fn.<locals>.<genexpr>ë  s    øè ø€ ÒE°Dˆt�u—|‘|×/Ñ/Ô/ÑEùs   ƒ"%FT)ÚinspectÚcurrentframeÚanyÚf_back)Úpatternsrf  s    @r$   Ú_ok_to_generate_guards_fnrl  Þ  sG   ø€ ò€Hô × Ñ Ó"€EØ
Ð
ÜÓE¸HÔEÔEØØ—‘ˆð Ñ
ð
 r&   c                 ó   — |xr
 t        «       }| j                  j                  D �ci c]  }|j                  dk7  sŒ|j                  |“Œ! }}| j                  j                  D �ci c]  }|j                  dk(  sŒ|j
                  |“Œ! }}t        j                  j                  | j                  t        j                  | j                  «      «      }|j                  j                  | j                  j                  «       t        j                  | «      } t        | j                  j                   | j                  j"                  «      | _        || _        | j&                  d   j(                  dk7  rt+        | «      } t-        || j.                  | j0                  | j2                  «       | j4                  d   j6                  x}r|j8                  nd }| j.                  j                   D �cg c]Z  }|j:                  t<        j>                  t<        j@                  t<        jB                  t<        jD                  fv r|j
                  nd ‘Œ\ }	}| j.                  j"                  D �
cg c]K  }
|
j:                  tF        jH                  tF        jJ                  tF        jL                  fv r|
j
                  nd ‘ŒM }}
|j                  j                  D ]�  }d }|j                  dk(  r|jO                  |j
                  «      }n)|j                  |v r|jO                  |j                  «      }tQ        |dtR        jT                  «      g|j                  d<   Œƒ | jV                  jX                  €t[        d«      ‚t]        ||	|| jV                  jX                  | jV                  j^                  |¬«      }ta        || jb                  | «      }|j                  j                  | j                  j                  «       |j                  }|je                  d¬«      }|�rN|�rK| jf                  �r>ti        j6                  |jj                  «      }tm        | jf                  |«      }g }| jn                  D ]  }|jq                  ts        ||«      «       Œ tu        || jb                  |«      }tw        | jn                  |«      }ty        ||«      }|j{                  |«       t}        ||«      |_?        t        j                  j€                  jƒ                  |«      }|j…                  |d	   «      5  |j‡                  d
t‰        |«      «      }||j                  d<   d d d «       |j‹                  «        |S c c}w c c}w c c}w c c}
w # 1 sw Y   Œ/xY w)Nr„   r   ÚTRAININGzExportedProgram.module()r™   z#ep.call_spec.in_spec cannot be None)rÊ   r…   éÿÿÿÿr�   Únn_module_stack)Frl  rˆ   rš   r†   r�   Útargetrs   r  ÚGraphModuler  ÚcopyÚdeepcopyr¤   rY   r   Ú_graph_signatureÚinput_specsÚoutput_specsÚ_graph_moduleÚ	verifiersÚdialectr   rê   rÚ   rÛ   rÜ   Úmodule_call_graphr\   rÊ   Úkindr   rä   ÚCONSTANT_TENSORrå   Ú
CUSTOM_OBJr   ÚBUFFER_MUTATIONÚUSER_INPUT_MUTATIONÚPARAMETER_MUTATIONr"   r   r   r¦   Ú	call_specr8   rœ   rØ   rÉ   r'  rŠ   r‰   r  rg  rv   r0  Ú_guards_coderL   r5  r]  rU   rc   rÐ   r‚   r�   Ú_utilsÚ#first_call_function_nn_module_stackrž   Úcall_moduler¾   r×   )r  Úcheck_guardsrª   Úsource_node_dictÚplaceholder_source_node_dictrÙ   ÚsigrÊ   r8   r”   rÉ   r±   Úsource_nodeÚ	unlift_gmrˆ   r6  rM   Ú	ep_guardsrR   rd   rC   Úroot_nn_module_stacks                         r$   Ú&_unlift_exported_program_lifted_statesr�  ò  sÍ  € ð  Ò?Ô$=Ó$?€Lð %'§H¡H§N¡NöØ °d·g±gÀÓ6Nˆ�	‰	�4‰ðÐð ð
 ')§h¡h§n¡nö$Ø"¸¿¹À=Ó8Pˆ�‰�TÑð$Ð ð $ô �X‰X×!Ñ! "§/¡/´4·=±=ÀÇÁÓ3JÓK€FØ
‡K�K×Ñ�r—‘×+Ñ+Ô,Ü	�‰�2‹€BÜ.Ø
×Ñ×'Ñ'¨×)<Ñ)<×)IÑ)Ió€BÔð €BÔð 
‡|�|�A�×Ñ *Ò,Ü" 2Ó&ˆä˜f b×&8Ñ&8¸"¿-¹-ÈÏÉÔVà)+×)=Ñ)=¸aÑ)@×)JÑ)JÐ"J #Ð"Jˆ×ÒÐQUð ð ×)Ñ)×5Ñ5ö'ð ð �|‰|ä× Ñ Ü×)Ñ)Ü×#Ñ#Ü×$Ñ$ð	ñð �NŠNð ñð'€Mð 'ð4 ×*Ñ*×7Ñ7ö)ð ð �}‰}ä×*Ñ*Ü×.Ñ.Ü×-Ñ-ðñð �OŠOð ñð)€Oð )ð —‘×"Ñ"ò 
ˆØˆØ�7‰7�mÒ#Ø6×:Ñ:¸4¿;¹;ÓG‰Kà�y‰yÐ,Ñ,Ø.×2Ñ2°4·9±9Ó=�äØØ*Ü ×'Ñ'óð"
ˆ�	‰	�+Òð
ð 
‡|�|×ÑÐ#ÜÐBÓCÐCÜØØØØ
�‰×ÑØ
�‰×ÑØ+ô€Fô .¨f°b×6JÑ6JÈBÓO€IØ‡N�N×Ñ˜"Ÿ/™/×.Ñ.Ô/ð �O‰O€EØ×#Ñ# }Ð#Ó5€LÚš¨×):Ó):Ü×Ñ 	× 1Ñ 1Ó2ˆÜ&Ø×ÑØó
ˆð ˆ	Ø—_‘_ò 	CˆEØ×ÑÔ-¨e°[ÓAÕBð	Cô 2Ø˜"×.Ñ.°ó
ˆô 3°2·?±?ÀKÓPˆÜ2°>À3ÓGˆØ×Ñ˜>Ô*Ü9¸+À{ÓSˆ	Ôä$Ÿx™xŸ™×RÑRØó 
Ðð ×"Ñ" <°Ñ#3Ó4ñ 	@Ø×$Ñ$ \´5¸Ó3FÓGˆDØ+?ˆD�I‰IÐ'Ñ(÷	@ð 	×ÑÔàÐùòuùò$ùò('ùò)÷Z	@ð 	@ús0   §U ¼U Á%U%Á:U%Ç*AU*É#AU/Ô+U4Õ4U=c                   ó   — e Zd ZdZd„ Zy)rr   z+
    Module class for guard functions.
    c                  ó   — y r    r)   )r   r=   s     r$   rv   zGuardsFn.forwardy  s   € Ør&   N)rú   rð   rñ   rû   rv   r)   r&   r$   rr   rr   t  s   „ ñór&   rr   r    )T)Urs  rg  r<  rŸ   Úcollections.abcr   Ú	itertoolsr   Útypingr   rS  rs   Útorch.utils._pytreerK  Ú_pytreer:   Útorch._export.non_strict_utilsr   r   r   Ú@torch._export.passes.add_runtime_assertions_for_constraints_passr	   Útorch._export.utilsr
   Útorch.export.unflattenr   r   Ú"torch.fx.experimental.proxy_tensorr   Útorch.fx.graphr   r   Útorch.fx.tracebackr   r   Útorch.utils._sympy.solver   Útorch.utils._sympy.value_rangesr   Ú_remove_effect_tokens_passr   Ú_tree_utilsr   Úexported_programr   r   r   r   ÚTreeSpecÚboolr7   ÚlistrB   r!   rU   rc   ÚKeyPathr‚   rt   Údisabler‹   r’   r  rr  r¾   r0   ÚNoder°   rÈ   rÓ   rØ   rê   r/   rì   rÿ   r'  r0  r5  rU  r]  rl  r�  ÚnnÚModulerr   r)   r&   r$   ú<module>r«     sÐ  ðã Û Û Û Ý $Ý Ý ã ã ß $Ð $÷ñ õ
õ Cß :Ý Pß 6ß ;Ý .Ý 7å =Ý '÷ó ð4�&—/‘/ð 4¨&¯/©/ð 4¸dó 4ð<¨v¯©ð À4ó ð&¨d°3©ió ð. ¨d°3©ió  ðFHØ�c‘ðHà §¡Ñ/óHðV ‡�×Ññó ðò@ð&*5Ø�‰×Ñð*5à˜C $™JÑ'ð*5ð ˆ4��U—X‘X—]‘]Ð"Ñ# T¨#¨u¯x©x¯}©}Ð*<Ñ%=Ð=Ñ>ó*5ðZ8
Ø�‰×Ñð8
à˜c D™jÑ)ð8
ð    U§X¡X§]¡]Ð 2Ñ3ð8
ð ˜S %§(¡(§-¡-Ð/Ñ0ð	8
ð
 
ó8
ð| +/ñØ�_‰_ðà�o‰o Ñ$ðð ˜C‘y 4Ñ'ðð ó	ðL +/ñ Ø�‰×Ñð à˜C $™JÑ'ð ð ˜c D™jÑ)ð ð �_‰_ð	 ð
 �o‰o Ñ$ð ð ˜C‘y 4Ñ'ó ðF&
Ø�H‰H× Ñ ð&
à)ð&
ð �S˜#�X‘ð&
ð �C˜�H‰~ð	&
ð
 
ó&
ôR
 $ô 
ô$$˜5Ÿ8™8×/Ñ/Ð;Võ $ðdØŸ™×,Ñ,ðdð 	ðdð ó	dòN@ð  ð ¸¸S¹	ó ðlØ�u—x‘x—}‘}Ñ%ðlà˜EŸL™L¨+Ð5Ñ6ðlð ! §¡Ñ0ólò^ð* '+ñØðà
‡X�X×ÑóôDˆu�x‰x�‰õ r&   