
    Ǆg)                        d dl Z d dlZ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m	Z	m
Z
mZmZmZmZmZ d dlZd dlmZ d dlmZ erd dl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m Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ejT                  dejV                  dejX                  dejZ                  dej\                  dej^                  diZ0	 	 dKdZ1	 	 	 	 dLdZ2dejf                  jh                  de	e5ef   fdZ6de	e5ef   dejf                  jh                  ddddfdZ7dejf                  jh                  fdZ8	 dMde	e5e5f   de5de5d e9fd!Z:d"eejf                  jv                     fd#Z<	 	 dNddddd$d%ee   d&ee    d'ee)   d(ee5   d)ee'   d*ee!   d+e9ddfd,Z=d-d.d/ejf                  jv                  de9fd0Z>d-d.d/ejf                  jv                  deej~                  j                     fd1Z@d-d.d/ejf                  jv                  de9fd2ZAd-d.d/ejf                  jv                  deej                     fd3ZCd-d.d/ejf                  jv                  de9fd4ZDd-d.d/ejf                  jv                  deej                     fd5ZEdejf                  jh                  dejf                  jh                  fd6ZFd7eejf                  jv                     deejf                  jv                     fd8ZG	 dOd7eejf                  jv                     deejf                  jv                     fd9ZHd7eejf                  jv                     deIfd:ZJd7eejf                  jv                     deejf                  jv                     fd;ZKd<ejf                  jv                  d=ejf                  jv                  ddfd>ZLd?ejf                  jv                  ddfd@ZMdej~                  j                  fdAZOdB ZPdejf                  jh                  ddfdCZQdejf                  jh                  dDddej~                  j                  dEe	e5ef   ddf
dFZRdGe	dHe9de	fdIZSdejf                  jh                  dej                  j                  j                  fdJZWy)P    N)	Parameter)AnyDictIterableListOptionalTupleTypeTYPE_CHECKING)detect_fake_mode)
FakeTensorConstantAttrMap)ExportedProgram)ExportGraphSignature)	InputKind
OutputKind)_register_pytree_nodeContextFlattenFuncFromDumpableContextFn
GetAttrKeyKeyPathkeystr
MappingKeySequenceKeyToDumpableContextFntree_flatten_with_pathUnflattenFunc p_b_c_obj_tokenreturnc                    ddl m}  |       }| j                  D ch c]7  }|j                  t        j
                  k(  r|j                  s|j                  9 }}|j                         D ]n  \  }}||v r|}	|j                  d      ^ }
}|
D ]  }t        |	|      }	 |	j                  j                  |d        t        |	||       |j                  ||       p |S c c}w )Nr   r   .)(torch._export.passes.lift_constants_passr   input_specskindr   BUFFER
persistenttargetitemssplitgetattr_bufferspopsetattradd)graph_signature	constantsmodr   constant_attrsspecnon_persistent_buffersnamevalue_modatomsattratoms                [/home/mcse/projects/flask_80/flask-venv/lib/python3.12/site-packages/torch/_export/utils.py_collect_and_set_constant_attrsrC   0   s     I$&N $//99	((( 	 
 !( (e))zz# 	'D4&D	' 	$%dE"5$'( #s   <Cr   new_sigc                 2   | j                   D ch c]7  }|j                  t        j                  k(  r|j                  s|j
                  9 }}|j                   D ]6  }|j                  t        j                  k(  s!|j
                  |v s0d|_        8 |S c c}w )NF)r*   r+   r   r,   r-   r.   )old_sigrD   r:   r;   s       rB   /_overwrite_signature_for_non_persistent_buffersrG   N   s     ''99	((( 	  ## $99	(((T[[<R-R#DO$ Ns   <Br8   c                    i }dt         j                  j                  dt        fd}| j                  j
                  D ]  }|j                  }|j                  }|j                  dk(  ry || |      }t        |t         j                  j                        rL|j                  dd      D ]  \  }}|||dz   |z   <    |j                  dd      D ]  \  }}|||dz   |z   <    |j                  d	k(  r2 || |      }t        |t         j                  j                        s|||<   |j                  d
k(  st        |j                  t         j                  j                        r%|j                   D ]U  }	|	j                  d	k(  st         j                  j"                  j$                  D ]  }
|
|v s||
   ||	j                     |
<    W  |S )a  
    Param/buffer metadata needs to be saved before lowering to aten IR
    because aten IR lifts them, as a result, automatic preservation doesn't work.
    This is intended to be called on the strict mode tracing right before lowering to
    aten IR OR run_decomposition pass.
    model	attr_namec                 v    |j                  d      ^ }}| }|D ]  }t        ||d       }|J  t        ||      S )Nr(   )r0   r1   )rI   rJ   prefixfieldtitems         rB   _getattrz0_collect_param_buffer_metadata.<locals>._getattrg   sO    "- 	!D4&A= =	! q%      call_moduleTF)recurseremove_duplicater(   get_attrcall_function)torchfxGraphModulestrgraphnodesr.   metaop
isinstancennModulenamed_parametersnamed_buffers_opsHigherOrderOperator_input_nodesproxy_COPY_META_FIELDS)r8   params_buffers_to_node_metarP   noder.   r]   	submoduler<   _argentrys              rB   _collect_param_buffer_metadataro   ^   s    #%!,, ! ! 		 Yyy77m# f-I)UXX__5(99 5  :   LGD! HL/t0CDL
  )66 5  7   LGD! HL/t0CDL
 77j  f-Ii)=)=>6:+F3
 77o%jKK77/
 (( Y66Z'!&!A!A Y D=MQRW[7

CEJYY7YB '&rQ   ri   gmc                 L   | j                         D ]&  }|j                  dd       |j                  dd       ( |j                  j                  D ]  }|j                  dk(  s|j
                  |j                  v rG|j                  |j
                     }|| v r*| |   j                         D ]  \  }}||j                  |<    |j
                  |j                  v s|j                  |j
                     }|| v s| |   j                         D ]  \  }}||j                  |<     y)zq
    Given that we collected param'buffer metadata before, we put them back in
    newly traced graph module
    nn_module_stackNstack_traceplaceholder)
valuesr3   r[   r\   r^   r.   inputs_to_parametersr/   r]   inputs_to_buffers)	ri   rp   rD   metadatarj   
param_namekvbuffer_names	            rB   )_populate_param_buffer_metadata_to_new_gmr}      s    0668 *&-]D)*  )77m#{{g:::$99$++F
!<< ;J G M M O )1'(		!){{g777%77D"== ;K H N N P )1'(		!))rQ   c                 J   | j                   j                  D cg c]-  }|j                  j                  dd       |j                  d   / }}t	        |       }||j
                  S |D ]4  }t        |t        j                        s|j                  j
                  c S  y c c}w )Nval)
r[   r\   r]   get_detect_fake_mode_from_gm	shape_envr_   rW   SymIntrj   )rp   rj   vals	fake_moder{   s        rB   _get_shape_env_from_gmr      s     HHNN99==%1 			%D  *"-I""" $a&66###$s   2B Fname_map	orig_namer<   is_placeholderc                 Z   || j                         v rt        j                  d|      }|r.|s,|j                  d      t	        |j                  d            }}nd}| d|dz    x}| j                         v r"|dz  }| d|dz    x}| j                         v r"|| |<   | |   S || |<   | |   S )a  
    Renames nodes to avoid name collisions, with suffixing.
    name_map: map from original name to new name
    orig_name: mapping key
    name: candidate name (potentially suffixed, e.g. mul_2)
    is_placeholder: if the node is a placeholder, avoid detecting suffix
    z
(.*)_(\d+)      r   rl   )ru   rematchgroupint)r   r   r<   r   r   ndup_names          rB   _rename_without_collisionsr      s     x   -kk!nc%++a.&9!DA"V1QUG,,x1BBFA #V1QUG,,x1BB& I #IrQ   input_placeholdersc                    dt         dt        fd}dd l}ddlm} ddlm} t        |      t        |       k7  r$t        dt        |        dt        |       d	      i }t        ||       D ]  \  \  }}	}
|
j                  j                  d
      }t        |t              ryt        |	t        j                        s t        d ||       dt!        |	             t        |j"                        t        |	j"                        k7  r/t        d ||       d|j"                   d|	j"                   d	      t%        t        |	j"                  |j"                              D ]  \  }\  }}t        |t        j&                        r4t        |j(                  j*                  j,                        dk(  rt/        t1        |j(                  j*                  j,                              }||v rH|j(                  j*                  j3                  |      }||k7  r
t        d ||       d| d| d|       t        |t        j&                        r!|j(                  j*                  j4                  snt        |j(                  j*                  |j6                        rt9        |      ||<   ny ||j;                  |j(                  j*                  |      |      }|9t        d|
j<                   d| d| d|j(                  j*                   d| d      t9        |d         ||<   |j(                  j*                  |v s |||j(                  j*                           \  }}|dkD  r"||k  rt        d ||       d| d| d|       |t>        j@                  k  s5||kD  s<t        d ||       d| d| d|       ||k7  s`t        |t        j&                        r"|j(                  j*                  j4                  st        d ||       d| d| d|        t        |t8        tB        t        f      st!        |	      t!        |      k7  s|	|k7  st        d ||       d| d|	        y )Nkey_pathr&   c                     | d   }t        |t              sJ |j                  dk(  rdt        | dd        S | d   }t        |t              sJ t        |      dd }| t        | dd        S )zFor a given index into the flat_args, return a human readable string
        describing how to access it, e.g. "*args["foo"][0].bar"
        r   z*argsr   Nr   )r_   r   idxr   r   rZ   )r   args_kwargs_key_path	kwarg_keyr<   s       rB   
get_keystrz6_check_input_constraints_for_graph.<locals>.get_keystr   s      ({.<<<##q(6(12,/011 Ii444y>!B'DVF8AB<0122rQ   r   )_convert_range_to_int)	try_solvez&Unexpected number of inputs (expected z, got )r   zExpected input at z to be a tensor, but got z,Unexpected number of dimensions in input at z.shape (expected r   z.shape[z] to be equal to z
, but got zExpected input z] = z to be of the form z, where z is an integerr   z] to be >= z] to be <= z to be equal to )"r   rZ   sympy@torch._export.passes.add_runtime_assertions_for_constraints_passr   torch.utils._sympy.solver   lenRuntimeErrorzipr]   r   r_   r   rW   Tensortypeshape	enumerater   rj   exprfree_symbolsnextitersubs	is_numberSymbolr   Eqr<   mathinffloat)r   flat_args_with_pathrange_constraintsr   r   r   r   unification_mapr   rm   rj   node_valjarg_dimnode_dimsymbolexisting_dimsolutionmin_valmax_vals                       rB   "_check_input_constraints_for_graphr      s   3W 3 3"  3
3'9#::/01<O8P7QQRT
 	
 02O!$%8:L!M [399=='h
+c5<<0"(H)=(>>WX\]`XaWbc  8>>"c#))n4"B:hCWBX Y!!) 0syykD 
 +4C		8>>4R*S H&&GX x6HMM..;;<A!$x}}'9'9'F'F"GHF0'/}}'9'9'>'>'O"l2"."4Z5I4J'RSQTTe#/.
7)!E#  'w=$+LL$5$5$?$?
 !)(--*<*<ellK
 ;>g, 7+4$)HHX]]-?-?$I6," $,#3*6*9$))GA3dSZR[ \77?}}7I7I6J(SYRZZh)j+& %&
 ?B(1+>NOF$;}}))->>+@-hmm.@.@A,( #Q;&0&2&8H9M8NgVWUXXc'.iz'%D'" !" #TXX-&0&2&8H9M8NgVWUXXc'.iz'%D'" !"
 (*&x>$,MM$6$6$@$@ %*0H1E0FgaSPa'j
7)= KHR 3s"34CyDN*cXo"(H)=(>>NxjXbcfbgh s[rQ   )serialized_type_nameto_dumpable_contextfrom_dumpable_contextreturn_none_fieldscls
flatten_fnunflatten_fnr   r   r   r   c          	          t        j                         s
J d         dt        dt        t        t           t
        f   ffd}dt        t           dt
        dt        f fd}dt        dt        t        t           t
        f   ffd}	n|||n|}|d u |d u z  rt        d	  d
      t         |||	||       y )Nz7Only dataclasses can be registered with this function: objr&   c                    g }g }g }t        j                  |       D ]\  }|j                  t        | |j                        }}|r#|j	                  |       |j	                  |       L|j	                  |       ^ |||gfS N)dataclassesfieldsr<   r1   append)r   	flattened
flat_names
none_namesfr<   r   r   s          rB   default_flatten_fnz=register_dataclass_as_pytree_node.<locals>.default_flatten_fnl  s    	

##C( 	(AQVV 4#D"4  %!!$'!!$'	( :z222rQ   ru   contextc           
      n    |\  }} di t        t        ||             t         j                  |      S )N )dictr   fromkeys)ru   r   r   r   r   s       rB   default_unflatten_fnz?register_dataclass_as_pytree_node.<locals>.default_unflatten_fny  s5    !(
JPT#j&12PdmmJ6OPPrQ   c                      |       \  }\  }}t        ||      D cg c]  \  }}t        |      |f c}}|fS c c}}w r   )r   r   )r   r   r   r   rz   r{   r   s         rB   default_flatten_fn_with_keyszGregister_dataclass_as_pytree_node.<locals>.default_flatten_fn_with_keys}  sC    .8o+	+J
/2:y/IJtq!A"JJVVJs   <z7Both to_dumpable_context and from_dumpable_context for z must be None or registered.)r   flatten_with_keys_fnr   r   )	r   is_dataclassr   r	   r   r   r   
ValueErrorr   )
r   r   r   r   r   r   r   r   r   r   s
   ``    `   rB   !register_dataclass_as_pytree_noder   ^  s    ## G	@FG 3 3d3i.@(A 3QXc] QW Q QW# W%S	78J2K W  *5;MJ#/#;<AULt#(=(EFEcU K% %
 	

 19/3rQ   programr   rj   c                 F    |j                   | j                  j                  v S )zM
    Checks if the given node is a parameter within the exported program
    )r<   r6   rv   r   rj   s     rB   is_paramr     s    
 99//DDDDrQ   c                     t        | |      r2| j                  j                  |j                     }| j                  |   S y)z
    Returns the parameter associated with the given node in the exported program.
    Returns None if the node is not a parameter within the exported program
    N)r   r6   rv   r<   
state_dict)r   rj   parameter_names      rB   	get_paramr     s<      00EEdiiP!!.11rQ   c                 F    |j                   | j                  j                  v S )zJ
    Checks if the given node is a buffer within the exported program
    )r<   r6   rw   r   s     rB   	is_bufferr     s    
 99//AAAArQ   c                     t        | |      rY| j                  j                  |j                     }|| j                  j                  v r| j
                  |   S | j                  |   S y)z
    Returns the buffer associated with the given node in the exported program.
    Returns None if the node is not a buffer within the exported program
    N)r   r6   rw   r<   r;   r7   r   )r   rj   r|   s      rB   
get_bufferr     sa     $--??		J'11HHH$$[11%%k22rQ   c                 F    |j                   | j                  j                  v S )zZ
    Checks if the given node is a lifted tensor constant within the exported program
    )r<   r6   !inputs_to_lifted_tensor_constantsr   s     rB   is_lifted_tensor_constantr     s     99//QQQQrQ   c                     t        | |      r2| j                  j                  |j                     }| j                  |   S y)z
    Returns the lifted tensor constant associated with the given node in the exported program.
    Returns None if the node is not a lifted tensor constant within the exported program
    N)r   r6   r   r<   r7   )r   rj   lifted_tensor_names      rB   get_lifted_tensor_constantr     sC     !$/$44VVII
   !344rQ   c                     ddl m} i d}| j                  j                  D ]  } ||      r|dz  }||<     || | fddd      }| j                  j                  |j                  _        |j                          |S )a;  
    sequential_split creates a new graph module that splits the input graph module into multiple submodules
    based on the node_call_back. It doesn't mutate the input graph module. The node_call_back should return
    True if the node is a delimiter.  Delimiter will be the first node in the next submodule.
    r   )split_moduler   c                     |    S r   r   )rj   	split_maps    rB   <lambda>z"sequential_split.<locals>.<lambda>  s    Yt_ rQ   T)keep_original_orderkeep_original_node_name)torch.fx.passes.split_moduler   r[   r\   _codegen	recompile)rp   node_call_backr   split_idrj   new_gmr   s         @rB   sequential_splitr     s     :IH #$MH"	$#
 

$  $F HH--FLL
MrQ   r\   c                 >    | D cg c]  } ||      s| c}S c c}w )z:Returns the nodes that match the node_call_back as a list.r   r\   r   rj   s      rB   nodes_filterr    s    ";TnT&:D;;;s   c                 L    t        | |r|nd       }t        |      dkD  r|d   S y)z
    Returns the first node that matches the node_call_back. If no node matches, returns None.
    When node_call_back is None, returns the first node in the node list.
    c                      y)NTr   rj   s    rB   r   znodes_first.<locals>.<lambda>  s    rQ   r   N)r  r   )r\   r   rets      rB   nodes_firstr    s,     unDU
VC
3x!|1vrQ   c                 ,    t        t        | |            S )z:Returns the number of nodes that match the node_call_back.)r   r  )r\   r   s     rB   nodes_countr
    s    |E>233rQ   c                 $    | D ]
  } ||        | S )z
    Sequentially visit the nodes list and invoke node_call_back on each element.
    Returns the nodes list after the node_call_back is invoked on each element.
    r   r  s      rB   	nodes_mapr    s     
  tLrQ   old_nodenew_nodec                     | j                  |       | j                  j                          | j                  j	                  |        y)z5
    Replace all uses of old_node with new_node.
    N)replace_all_uses_withusersclearr[   
erase_node)r  r  s     rB   node_replace_r  "  s4     ""8,NNNNh'rQ   call_mod_nodec                    | j                   dk(  sJ | j                  j                  }t        | j                  t
              sJ t        || j                        }d |j                  j                  D        }d |j                  j                  D        }|j                  j                  D cg c]  }|j                   dk(  s| }}t        || j                        D ]7  \  }}t        |t        j                  j                        sJ t        ||       9 |j                  j                  |       5  |D ])  }|j                  j                  |      }	t        ||	       + t!        |      dkD  r4t!        |      dk(  rt!        |d   j                        dk(  sJ |d   j                  d   t        t        j                  j                        r'j"                  j%                          t        |        nt        t&        t(        f      r~D ]   }|j"                  j+                  |d          " t-        t'        | j"                  j/                               d       }
t1        |
fd       | j                  j3                  |        n3t5        d	t7               d
      | j                  j3                  |        ddd       |j9                          |j;                          |S c c}w # 1 sw Y   0xY w)z
    Inline the submodule of the given node into the parent module.
    Note: we only support the case where submodule takes tensors inputs.
    rR   c              3   @   K   | ]  }|j                   d k(  s|  yw)rt   Nr^   .0rj   s     rB   	<genexpr>znode_inline_.<locals>.<genexpr>6  s     
KD$'']2J4
Ks   c              3   >   K   | ]  }|j                   d vs|  yw))rt   outputNr  r  s     rB   r  znode_inline_.<locals>.<genexpr>7  s!      tww>W/Ws   r  r   r   c                 ^    | j                   dk(  xr | j                  t        j                  k(  S )NrV   )r^   r.   operatorgetitemr  s    rB   r   znode_inline_.<locals>.<lambda>V  s)    O!; "8x'7'77 rQ   c                 <    t        | | j                  d            S )Nr   )r  args)get_item_node
new_outputs    rB   r   znode_inline_.<locals>.<lambda>\  s"    -%"=#5#5a#89+ rQ   zUnsupported output type z2. Expect it to be a Node or a list/tuple of Nodes.N)r^   r[   owning_moduler_   r.   rZ   r1   r\   r   r"  rW   rX   Noder  inserting_before	node_copyr   r  r  listtupler3   r  keysr  r  NotImplementedErrorr   delete_all_unused_submodulesr   )r  rp   sub_gmphsbodyrj   r  phrm   r  get_item_usersr$  s              @rB   node_inline_r3  +  s   
 },,,				*	*Bm**C000R--.F
KFLL..
KC++D  &||11ItTWW5HdIFIsM../ C#uxx}}---b# 
	"	"=	1 ': 	*Dxx))$/H$)	* v;?v;!#F1INN(;q(@@@*J*ehhmm4   &&(mZ8Ju6& .DJJNN6!9-. ".,,11348" " ##..}=).tJ/?.@@rs  **=9O':R ##%LLNIc J': ':s   -K*K*3FK//K8c                    t        j                  | j                        }|j                  d   }dt        j
                  i}g }|j                         D ]d  \  }}t        |j                  |      D cg c]  }|j                   }}|D ]-  }	|	dk(  r	|j                  t        j                  |	|             / f t        j                  |      S c c}w )z
    Get source code and parse argument names using AST. The function returns
    a signature of the forward() function.

    # TODO: Directly provide inspect.signature compatible TS-d module.
    r   r"  self)
parameters)astparsecoder0  r   POSITIONAL_OR_KEYWORDr/   r1   r"  rm   r   inspect	Signature)
r8   ast_modast_func_defarg_type_map
param_listarg_type
param_typeaarg_name_listarg_names
             rB   &_get_torch_jit_trace_forward_signaturerF  n  s     ii!G$+LLOL I;;<L J , 2 2 4 G*(/0A0A8(LM1MM% 	GH6!g//*EF	GG 
33 Ns   1Cc                 r   t        | t        j                  j                  t        j                  j                  f      r?t        |       }t        |j                        t        |      t        |      z   k(  s&J d       t        j                  | j                        } |j                  |i |j                  S )NzyArguments other than POSITIONAL_OR_KEYWORD kinds in forward() are not supported in _get_torch_jit_trace_forward_signature)r_   rW   jitScriptModuleTracedModulerF  r   r6  r;  	signatureforwardbind	arguments)r8   	fake_argsfake_kwargssigs       rB   _bind_signature_to_inputsrR    s    #		..		0F0FGH4S9 3>>"c)ns;7G&GG 	
J	
G
 ,388Y.+.888rQ   c                    g }| j                   j                  D ]p  }|j                  dk(  st        |j                  t
        j                  j                        sC|j                  j                  dk(  r`|j                  \  }}}}|j                  t        | |j                        |f       |j                  t        | |j                        |f       |j                  j                  dk(  rG|j                  d   |j                  dd }}|j                  t        | |j                        |f       |j                  j                  dk(  s7|j                  \  }	}
}|j                  t        | |	j                        |
|z   f       s |D ]  \  }}i }t        |j                   j                        D ]q  \  }}|t        |      k  r8||   j                  ||j                  <   ||   j                  x|_        |_        Lt        ||j                  |j                        |_        s t!        |       |j#                           y)a0  
    Propagate placeholder names from the top-level graph into HigherOrderOp subgraphs,
    and handle collisions with non-placeholders by count suffixing.
    Different HOO subgraph types have different input schemas, so we first enumerate them
    and gather the top-level named placeholder nodes.
    rV   condwrap_with_set_grad_enabledr   r   Nmap_impl)r[   r\   r^   r_   r.   rW   rd   re   _name_argsr   r1   r   r   r<   r   _name_hoo_subgraph_placeholdersr   )rp   subgraph_ph_tuplesrj   rl   
true_graphfalse_graph	cond_argssubgraphr/  
body_grapharrayr"  hoo_phsr   is                  rB   rY  rY    s    RT 77o%*KK77+
 {{  F*8<

5:{I"))72z7H7H+I9*UV"))72{7I7I+JI*VW""&BB $

1tzz!"~#"))72x+G*MN""j0*.**'
E4"))R!2!23UT\B& 0 '#% !5!56 	WGAt3w<&-ajoo#*1!*//9	DK6xDIIV		W 	(1rQ   export_graph_signaturer7   c           
      >   d }d i }t        |||      }	t        |	      \  }
}|j                  D cg c]5  }|j                  t        j
                  k(  r|j                  j                  7 }}t        |
|      D ]J  \  \  }}}|st        ||t        t        j
                     dj                  fd|D              z   d       L |j                  D ]  }|j                  t        j
                  k(  r!|j                  t        j                  k(  rd}n  ||j                        j                         }t        j                   dd|      }t        ||j                  j                  t        |j                     |z   d        | j"                  j$                  D ]3  }|j&                  d	k(  rt        ||j                  |j                         5 | j"                  j$                  D ]`  }|j&                  d	k(  r,|j                  |v sJ ||j                     x|_        |_        >|j                  |v sM||j                     |_        b t)        |        | j+                          |j                  D ]  }|j                  j                  |v sJ ||j                  j                     |j                  _        |j                  t        j,                  k(  sc|j                  |v sr||j                     d
d |_         |j.                  D ]  }|j                  j                  |v r(||j                  j                     |j                  _        |j                  t0        j2                  k(  sa|j                  |v sp||j                     |_         t5        |j7                               D ]o  }||   }||v st9        |t:        j<                        r(||   }||k7  s3t        j>                  d|      sJ|t        t        j,                     |z   k7  sh|||<   ||= q yc c}w )aQ  
    This pass is run at the end of _export_non_strict() to assign better placeholder node names:
        - User inputs:
            These follow the signature of mod.forward(), e.g. forward(x, y) produces nodes x, y.
            For nested inputs from dictionaries, lists, tuples, or dataclasses,
            the names are a concatenation of the path to the tensor.
                e.g. x = {
                    'a': torch.randn(),
                    'b': [torch.randn(), torch.randn()]
                }
            produces nodes x_a, x_b_0, x_b_1.
        - Parameters/buffers/constants/custom objects:
            These follow the FQN of the object, prefixed by "p", "b", "c", "obj" respectively.
                e.g. self.bar.l0.weight produces "p_bar_l0_weight".
        - Effect tokens:
            These are named token, token_1, ...
    c                     | j                  d      r| t        d      d  } n| j                  d      r| t        d      d  } t        j                  dd|       } | S )N
L__self___self_[^a-zA-Z0-9]rl   )
startswithr   r   subxs    rB   _strip_namez,placeholder_naming_pass.<locals>._strip_name  sS    <<%#l#%&A\\'"#g,.!AFF?C+rQ   c                 0   t        | t              r,t        j                  ddt	        | j
                              } | S t        | t              rt	        | j                        S t        | t              r| j                  S t        dt        |        d|        )Nrh  rl   zPytree key of type z not handled for )r_   r   r   rj  rZ   keyr   r   r   r<   r   r   rk  s    rB   _extract_pytree_keyz4placeholder_naming_pass.<locals>._extract_pytree_key  st    a$SZ8AH;'quu::&66M!4T!WI=NqcRSSrQ   rl   c              3   J   K   | ]  } |      j                           y wr   )lower)r  rl  rp  s     rB   r  z*placeholder_naming_pass.<locals>.<genexpr>  s      La.q1779Ls    #T)r   r    rh  rt      Nz
arg(\d+)_1) rR  r   r*   r+   r   
USER_INPUTrm   r<   r   r   placeholder_prefixesjoinTOKENr.   rr  r   rj  r[   r\   r^   rY  r   
CUSTOM_OBJoutput_specsr   USER_INPUT_MUTATIONr)  r+  r_   rW   r   r   )rp   rc  r8   rO  rP  fake_params_buffersr7   rm  r   combined_argsr   rl   r:   user_input_namesarg_pathrm   user_input_name	base_namerj   r<   constantnew_namerp  s                         @rB   placeholder_naming_passr    s   6	T  "H .c9kJM3MB +6699	,,, 	  -00CEU,V (3&$Y%9%9:((L8LLM# '22 
99	,,,99	'I#DKK0668IFF?C;	"HHMM +i7		

(  C77m#"8TYY		BC  ,77m#99(((&.tyy&99DIYY(" +DI, $B' LLN '22 4xx}}((( /II---$++2I"4;;/3DK4 '33 088==H$$TXX]]3DHHM99
6664;;(;R"4;;/DK	0 Y^^%& $T?8Jell%
  ~HD HH]D1 4Y5I5I JT QQ&.	(#dO$Us   :Pr   in_placec                    |r6| j                         D ]!  \  }}t        |d      st        | |   d       # | S i }| j                         D ]8  \  }}t        |d      r"|j                         j	                         ||<   4|||<   : |S )z
    If `in_place` is false, return a new copy of `state_dict` with "proxy" removed from `v.__dict__`.
    `v` is the values in the dictionary.
    If `in_place` is true, modify `state_dict` in place.
    rg   )r/   hasattrdelattrclonedetach)r   r  rz   r{   new_state_dicts        rB   remove_proxy_from_state_dictr  M  s     $$& 	0DAqq'"
1w/	0 $$& 	&DAqq'"$%GGI$4$4$6q!$%q!		&
 rQ   c                 D   g }g }| j                   j                  D ]  }|j                  dk(  rMd|j                  v r?|j                  d   }|2t	        |t
        j                        sM|j                  |       _t        |      dk(  snd|j                  v sd|j                  v sd}d|j                  v r|j                  d   }nd|j                  v r|j                  d   }|t	        |t
        j                        s|j                  |        t        ||z         S )a  
    For a given graph module, we look at the "val" of placeholder nodes to find the fake inputs.
    Additionally, if gm doesn't have placeholders, we further look at the "example_value" or "val" of other nodes.
    If no fake mode is found, we return None for fake_mode.
    rt   r   Nr   example_value)
r[   r\   r^   r]   r_   rW   r   r   r   r   )rp   	fake_inps	fake_valsrj   fake_vals        rB   r   r   b  s     %'I$&I +77m#(:yy'H#
8U\\(J  *^q tyy(ETYY,>H$))+99_5$))#99U+#
8U\\(J  *+  I	122rQ   )r&   r   )rF   r   rD   r   )F)NNr   )Xr7  r   r;  r   r  r   r   typingr   r   r   r   r   r	   r
   r   rW   torch._guardsr   torch._subclasses.fake_tensorr   r)   r   torch.exportr   torch.export.graph_signaturer   r   r   torch.utils._pytreer   r   r   r   r   r   r   r   r   r   r   r   rt  	PARAMETERr,   CONSTANT_TENSORrx  rw  ru  rC   rG   rX   rY   rZ   ro   r}   r   boolr   r&  r   r   r   r`   r   r   r   r   r   r   r   r  r  r   r
  r  r  r3  ra   rF  rR  rY  r  r  _subclassesfake_tensorFakeTensorModer   r   rQ   rB   <module>r     s   
     	  R R R  * 4 H,A >   " "dt&OOW <#.D 3'(<(< 3'c3h 3'l)!%c3h)) $) 
	)8$uxx33 $& !	38n  	:UXX]]+H )-,04
 +/9==A$4	c4%4 =)4
 #3-4 ""564 $$9:4 4 
4nE' Euxx}} E E
((-- ehh  ! B( B B$ B
((-- ell&RR
((--R 
R
((-- ell$-- %((BVBV 8<UXX]]+ <UXX]]@S < 04

ehhmm
4tEHHMM* 4s 4
T%((--( T%((--=P (EHHMM (UXX]] (t (@ @$ @F4 429'(<(< ' 'TJ$J$2J$ 
J$ CH~J$ 
J$ZT T d *33
""113rQ   