
    %Vji                     b   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Zd dlZd dlZd dl	m
Z
 d dlmZ d dlmZ d dlmZmZ d dlmZmZmZmZmZ d dlZd dl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$ er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/ d dl0m1Z1m2Z2 d dl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ e.jA        de.jB        de.jC        de.jD        de.jE        de.jF        diZGdaH	 	 ddZIdejJ        jK        fdZL	 	 dd"ZM	 	 	 	 dd%ZNdejJ        jK        deOePef         fd&ZQd' ZRd(eOePef         d)ejJ        jK        d$d!ddfd*ZSd)ejJ        jK        fd+ZT	 dd,eOePePf         d-eOePeUf         d.eVeP         d/ePd0ePd1eWfd2ZXd3e:dePfd4ZY	 dd5eeUejZ        f         d6eUd7e:d8eeU         ddf
d9Z[d:e\ejJ        j]                 ddfd;Z^	 	 dddddd<d=e_e         d>ee7         d?ee@         d@eeP         dAee>         dBee8         dCeWddfdDZ`dEdFdGejJ        j]        deWfdHZadEdFdGejJ        j]        deejb        j                 fdIZcdEdFdGejJ        j]        deWfdJZddEdFdGejJ        j]        deeje                 fdKZfdEdFdGejJ        j]        deWfdLZgdEdFdGejJ        j]        deeje                 fdMZhd)ejJ        jK        dNeejJ        j]        geejJ        j]        eWf         f         dejJ        jK        fdOZidPe\ejJ        j]                 de\ejJ        j]                 fdQZjedR             Zkd)ejJ        jK        ddfdSZld)ejJ        jK        fdTZm	 ddPe\ejJ        j]                 deejJ        j]                 fdUZndPe\ejJ        j]                 deUfdVZodPe\ejJ        j]                 de\ejJ        j]                 fdWZpdXejJ        j]        dYejJ        j]        ddfdZZqd)ejJ        jK        dejb        jr        ddfd[Zsd\ejJ        j]        deejJ        jK                 fd]Ztdejb        jr        deju        fd^Zvd_ Zwd` Zxd)ejJ        jK        ddfdaZyd)ejJ        jK        dbd!dejb        jr        dceOePef         ddf
ddZzdeeOdfeWdeOfdgZ{d)ejJ        jK        deej|        j}        j                 fdhZ~edejb        jr        fdi            ZdjdkdeWfdlZdjdkdeWfdmZdjdkdeWfdnZdjdkdeWfdoZddpZdq ZddsZ ej        dtu          deVdk         fdv            Zdwej        j        deVdk         fdxZdeVdk         fdyZddzZed{             Zd|edejb        jr        deOePeeje        ejb        j        f         f         fd}Zd=e_ejb        jr                 ddfd~Zd=e_ejb        jr                 ddfdZd Zd Z G d dejb        jr                  Zd ZdS )    N)defaultdict)Iterable)contextmanager)ismethod	Parameter)AnyCallableOptionalTYPE_CHECKINGUnion)detect_fake_mode)
FakeTensorFakeTensorMode)FunctionalTensor)#first_call_function_nn_module_stack)PreDispatchTorchFunctionMode)insert_deferred_runtime_assertsConstantAttrMap)OperatorBase)ExportedProgram)ExportGraphSignature)CustomObjArgument	InputKind
OutputKind)_deregister_pytree_flatten_specregister_pytree_flatten_spec)_deregister_pytree_node_register_pytree_nodeContextFlattenFuncFromDumpableContextFn
GetAttrKeyKeyPathkeystr
MappingKeySequenceKeyToDumpableContextFntree_flatten_with_pathUnflattenFunc p_b_c_obj_tokenFreturnr   c                 h   ddl m}  |            }d | j        D             }|                                D ]{\  }}||v r
|}|                    d          ^ }	}
|	D ]}t          ||          }|j                            |
d            t          ||
|           |	                    ||           ||S )Nr   r   c                 T    h | ]%}|j         t          j        k    |j        |j        &S  kindr   BUFFER
persistenttarget.0specs     M/root/voice-cloning/.venv/lib/python3.11/site-packages/torch/_export/utils.py	<setcomp>z2_collect_and_set_constant_attrs.<locals>.<setcomp>L   ;       9	(((( 	(((    .)
(torch._export.passes.lift_constants_passr   input_specsitemssplitgetattr_bufferspopsetattradd)graph_signature	constantsmodr   constant_attrsnon_persistent_buffersnamevalue_modatomsattratoms               r=   _collect_and_set_constant_attrsrV   B   s     IHHHHH$_&&N #/  
 !(( ( (e)))zz# 	' 	'D4&&DD$%%%dE"""5$''''r@   rM   c                    ddl m}m} t                      }| j        j        D ]}|j        dk    rt          j        j	        
                    | |j                  }t          |t          j                  ro|j        |vrf|j        |vr]t          j        j	                            | |j                    ||| |j        |j        d           |                    |j                   |                                  |S )Nr   )_assign_attr	_AttrKindget_attrF)torch.export.unflattenrX   rY   setgraphnodesoptorchfxgraph_module	_get_attrr9   
isinstanceTensor	_del_attrr7   rJ   	recompile)rM   
state_dictrO   rX   rY   temp_registered_constantsnoder9   s           r=   _register_constants_as_buffersrk   `   s     ?>>>>>>> #	 ? ?7j  X*44S$+FFF&%,// ? Kz11K'===H)33CEEE Ldk9;KUSSS-11$+>>>MMOOO$$r@   sigr   c                     | j         D ]#}|j        |v rt          j        |_        d |_        $| j        D ]8}|j        t          j        k    r!|j        |v rt          d|j         d          9| S )Nz	Constant z< is mutated in the forward method. Pls register it as buffer)
rC   r9   r   CONSTANT_TENSORr6   r8   output_specsr   BUFFER_MUTATIONRuntimeError)rl   ri   r<   s      r=   7_override_graph_signature_for_temp_registered_constantsrr   z   s      # #;333!1DI"DO   I333888eDKeee   Jr@   old_signew_sigc                     d | j         D             }|j         D ]'}|j        t          j        k    r|j        |v rd|_        (|S )Nc                 T    h | ]%}|j         t          j        k    |j        |j        &S r4   r5   r:   s     r=   r>   zB_overwrite_signature_for_non_persistent_buffers.<locals>.<setcomp>   r?   r@   F)rC   r6   r   r7   r9   r8   )rs   rt   rO   r<   s       r=   /_overwrite_signature_for_non_persistent_buffersrw      sb     '   # $ $9	(((T[<R-R-R#DONr@   c                    i }dt           j        j        dt          fd}| j        j        D ]P}|j        }|j        }|j        dk    r{ || |          }t          |t           j
        j                  rP|                    dd          D ]\  }}|||dz   |z   <   |                    dd          D ]\  }}|||dz   |z   <   |j        d	k    r0 || |          }t          |t           j        j                  s|||<   |j        d
k    rst          |j        t           j        j                  sO|j        D ]G}	|	j        d	k    r:t           j        j        j        D ]#}
|
dk    r	|
|v r||
         ||	j                 |
<   $HR|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                     |                     d          ^ }}| }|D ]}t          ||d           }|J t          ||          S )NrA   )rE   rF   )ry   rz   prefixfieldtitems         r=   _getattrz0_collect_param_buffer_metadata.<locals>._getattr   sW    "-- 	! 	!D4&&A====q%   r@   call_moduleTF)recurseremove_duplicaterA   rZ   call_functioncustom)r`   ra   GraphModulestrr]   r^   r9   metar_   rd   nnModulenamed_parametersnamed_buffers_opsHigherOrderOperator_input_nodesproxy_COPY_META_FIELDS)rM   params_buffers_to_node_metar   rj   r9   r   	submodulerP   _argentrys              r=   _collect_param_buffer_metadatar      s    #%!, ! ! ! ! ! 	 "Y "Yy7m## f--I)UX_55 	L(99 5  :     L LGD! HL/t0CDD(66 5  7     L LGD! HL/t0CDD7j   f--Ii)=>> ;6:+F3
 7o%%jK7/
 /
% ( Y Y6Z''!&!A Y Y H,,$ D==MQRW[7
CEJ&&r@   c                  .   t           j                                        sd S t           j                                        } d | D             }t          |          dk    sJ dt          |                       t          |          dk    rd S |d         }|S )Nc                 <    g | ]}t          |t                    |S r4   )rd   r   )r;   modes     r=   
<listcomp>z?_maybe_find_pre_dispatch_tf_mode_for_export.<locals>.<listcomp>   s9       d899  r@      z6Expected only one PreDispatchTorchFunctionMode, found r   )r`   _C_is_torch_function_mode_enabled	overrides _get_current_function_mode_stacklen)torch_function_mode_stackpre_dispatch_tf_modesr   s      r=   +_maybe_find_pre_dispatch_tf_mode_for_exportr      s    83355 t % P P R R -   $%%***]EZA[A[]] +**  !!Q&&t #DKr@   r   gmc                    |                                  D ].}|                    dd           |                    dd           /|j        j        D ]}|j        dk    r|j        |j        v r@|j        |j                 }|| v r*| |                                         D ]\  }}||j        |<   |j        |j	        v r@|j	        |j                 }|| v r*| |                                         D ]\  }}||j        |<   dS )zq
    Given that we collected param'buffer metadata before, we put them back in
    newly traced graph module
    nn_module_stackNstack_traceplaceholder)
valuesrH   r]   r^   r_   r9   inputs_to_parametersrD   r   inputs_to_buffers)	r   r   rt   metadatarj   
param_namekvbuffer_names	            r=   )_populate_param_buffer_metadata_to_new_gmr      s.    06688 * *&---]D)))) ) )7m##{g:::$9$+F
!<<< ;J G M M O O ) )1'(	!{g777%7D"=== ;K H N N P P ) )1'(	!) )r@   c                     d | j         j        D             }t          |           }||j        S |D ]*}t	          |t
          j                  r|j        j        c S +d S )Nc                 ^    g | ]*}|j                             d d          |j         d          +S )valN)r   getr;   rj   s     r=   r   z*_get_shape_env_from_gm.<locals>.<listcomp>  s?       9==%%1 		%111r@   )r]   r^   _detect_fake_mode_from_gm	shape_envrd   r`   SymIntrj   )r   vals	fake_moder   s       r=   _get_shape_env_from_gmr   
  s     HN  D *"--I"" $ $a&& 	$6####	$$ $r@   name_mapfind_available
used_names	orig_namerP   is_placeholderc                    t          j        d|          }|}|r.|s,|                    d          |                    d          }	}|}|}
|
|v r| d||         dz    }
t          j        d|
          }|rU|                    d          |                    d          }	}t          |	          ||         k    rt          |	          ||<   |
| |<   |                    |
           | |         S )ai  
    Renames nodes to avoid name collisions, with suffixing.
    name_map: map from original name to new name
    find_available: map prefix to available suffix
    used_names: cache of used names
    orig_name: mapping key
    name: candidate name (potentially suffixed, e.g. mul_2)
    is_placeholder: if the node is a placeholder, avoid detecting suffix
    
(.*)_(\d+)r      r   )rematchgroupintrJ   )r   r   r   r   rP   r   r   keyr|   nnew_names              r=   _rename_without_collisionsr     s    " H]D))E
C ^ KKNNEKKNNH:55N3/!355H]H--E ,KKNNEKKNNq66N6***%(VVN6""HYNN8Ir@   key_pathc                 :   | d         }t          |t                    sJ |j        dk    rdt          | dd                    S | d         }t          |t          t
          f          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   )rd   r'   idxr%   r#   r&   r   )r   args_kwargs_key_path	kwarg_keyrP   s       r=   
get_keystrr   A  s     $A;*K888881$$-vhqrrl++---QK	)j*%=>>>>>9~~ad#.x|,,...r@   symintr   keypathic                    ddl m} t          |t          j                  r|j        j        j        rt          ||          rd S dd l}ddl	m
} ddlm}	 t          | t          j                  rt          | j        j        j                  dk    rt          t!          | j        j        j                            }
|
|v rX| j        j                            |          }||k    r2t%          |          }|	|d| dz  }t'          d| d	| d
|           nt          | j        j        |j                  rt+          |          ||
<   n |	|                    | j        j        |          |
          }|@t%          |          }|	|d| dz  }t'          d| d| d| j        j         d|
 d	          t+          |d                   ||
<   | j        j        |v r ||| j        j                           \  }}|dk    r8||k     r2t%          |          }|	|d| dz  }t'          d| d| d
|           |t.          j        k     r:||k    r6t%          |          }|	|d| dz  }t'          d| d| d
|           d S d S d S t          | t          j                  r| j        j        j        sd S |t+          |           k    r3t%          |          }|	|d| dz  }t'          d| d	|  d
| d          d S )Nr   )_IntWrapper)_convert_range_to_int)	try_solver   z.shape[]Expected input at  to be equal to 
, but got zExpected input z = z to be of the form z, where z is an integerr   z
 to be >= z
 to be <= zt. If you meant for this dimension to be dynamic, please re-export and specify dynamic_shapes (e.g. with Dim.DYNAMIC))torch.export.dynamic_shapesr   rd   r`   r   rj   expr	is_numbersympy@torch._export.passes.add_runtime_assertions_for_constraints_passr   torch.utils._sympy.solver   r   free_symbolsnextitersubsr   rq   Symbolr   Eqmathinf)r   r   range_constraintsunification_mapr   r   r   r   r   r   symbolexisting_dimpathsolutionmin_valmax_vals                   r=   _check_symintr   S  s    877777 	3%%' c;'' 	LLL      322222&%,'' @
C0@0M,N,NRS,S,Sd6;+899::_$$!;+00AALl""!'**=NaNNN*D"\\\|\\WZ\\  	 # &+*EL99 ?
 +.c((''$9UXXfk.>%D%DfMM#%g..D}!.&X$ X X3 X X'-{'7X XAGX X X  
 /2(1+.>.>OF+;00044!&+"23   GW {{==%g..D}!.&UTUUWUUPSUU   !!==%g..D}!.&UTUUWUUPSUU  % 10 "! = 
FEL	)	) 
&+2B2L 
 		F		'""=NaNNN"D& & &v & & & & &
 
 	
	 
	r@   input_placeholdersc           
      R   dd l }t          |          t          |           k    r0t          dt          |            dt          |           d          i }t          ||           D ]\  \  }}}|j                            d          }t          |t                    rt          |t          j	                  s/t          dt          |           dt          |                     t          |j                  t          |j                  k    r0t          dt          |           d	|j         d|j         d          t          t          |j        |j                            D ]\  }	\  }
}t          ||
||||	           !t          |t          t           t"          f          rMt          |          t          |          k    s||k    r%t          dt          |           d
| d|           t          |t          j                  rt          |||||d            d S )Nr   z&Unexpected number of inputs (expected z, got )r   r   z to be a tensor, but got z,Unexpected number of dimensions in input at z.shape (expected r   r   )r   r   rq   zipr   r   rd   r   r`   re   r   typeshape	enumerater   r   floatr   r   )r   flat_args_with_pathr   r   r   r   r   rj   node_valjarg_dimnode_dims               r=   "_check_input_constraints_for_graphr    s    LLL
3'9#:#:::T/00T T8;<O8P8PT T T
 
 	
 02O!$%8:L!M!M  39==''h
++ 	c5<00 "cH)=)=ccX\]`XaXacc   8>""c#)nn44"D:hCWCW D D!)D D7:yD D D  
 +4C	8>4R4R*S*S  &&GXg'8/8UV   
 3s"344 	CyyDNN**cXoo"hH)=)=hhxhhcfhh   /> %,// 	#0/8T  3 r@   )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           |||	||           d S )Nz7Only dataclasses can be registered with this function: objr1   c                 
   g }g }g }t          j        |           D ]b}|j        t          | |j                  }}|r+|                    |           |                    |           M|                    |           c|||gfS N)dataclassesfieldsrP   rF   append)r  	flattened
flat_names
none_namesfrP   r   r  s          r=   default_flatten_fnz=register_dataclass_as_pytree_node.<locals>.default_flatten_fn  s    	

#C(( 	( 	(AQV 4 4#D"4  %%%!!$''''!!$'''':z222r@   r   contextc           
          |\  }} di t          t          ||                     t                               |          S )Nr4   )dictr   fromkeys)r   r  r  r  r	  s       r=   default_unflatten_fnz?register_dataclass_as_pytree_node.<locals>.default_unflatten_fn  sF    !(
JsPPT#j&1122PdmmJ6O6OPPPr@   c                 ^     |           \  }\  }}d t          ||          D             |fS )Nc                 6    g | ]\  }}t          |          |fS r4   r&   r;   r   r   s      r=   r   z[register_dataclass_as_pytree_node.<locals>.default_flatten_fn_with_keys.<locals>.<listcomp>  '    JJJtq!A"JJJr@   r   )r  r  r  _none_namesr
  s       r=   default_flatten_fn_with_keyszGregister_dataclass_as_pytree_node.<locals>.default_flatten_fn_with_keys  s=    /9z#,	,JJJs:y/I/IJJJJVVr@   z7Both to_dumpable_context and from_dumpable_context for z must be None or registered.r  flatten_with_keys_fnr  r  )	r  is_dataclassr   tuplelistr    r   
ValueErrorr   )
r	  r
  r  r  r  r  r  r  r  r$  s
   ``    `   r=   !register_dataclass_as_pytree_noder+    s    #C((  G#GG (3 3d3i.@(A 3 3 3 3 3 3QXc] QW Q Q Q Q Q Q QW# W%S	78J2K W W W W W W  *5;MJ#/#;<<AULt#(=(EF 
%c % % %
 
 	

 19/3     r@   programr   rj   c                 (    |j         | j        j        v S )zM
    Checks if the given node is a parameter within the exported program
    )rP   rK   r   r,  rj   s     r=   is_paramr/    s    
 9/DDDr@   c                 n    t          | |          r$| j        j        |j                 }| j        |         S dS )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/  rK   r   rP   rh   )r,  rj   parameter_names      r=   	get_paramr2    s;      2 0EdiP!.114r@   c                 (    |j         | j        j        v S )zJ
    Checks if the given node is a buffer within the exported program
    )rP   rK   r   r.  s     r=   	is_bufferr4  ,  s    
 9/AAAr@   c                     t          | |          r?| j        j        |j                 }|| j        j        v r| j        |         S | j        |         S dS )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)r4  rK   r   rP   rO   rL   rh   )r,  rj   r   s      r=   
get_bufferr6  4  sZ     $ 3-?	J'1HHH$[11%k224r@   c                 (    |j         | j        j        v S )zZ
    Checks if the given node is a lifted tensor constant within the exported program
    )rP   rK   !inputs_to_lifted_tensor_constantsr.  s     r=   is_lifted_tensor_constantr9  G  s     9/QQQr@   c                 n    t          | |          r$| j        j        |j                 }| j        |         S dS )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)r9  rK   r8  rP   rL   )r,  rj   lifted_tensor_names      r=   get_lifted_tensor_constantr<  R  sB     !$// 5$4VI
  !3444r@   node_call_backc                     ddl m} i d}| j        j        D ]} ||          r|dz  }||<    || | fddd          }| 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  r4   )rj   	split_maps    r=   <lambda>z"sequential_split.<locals>.<lambda>y  s    Yt_ r@   T)keep_original_orderkeep_original_node_name)torch.fx.passes.split_moduler?  r]   r^   _codegenrg   )r   r=  r?  split_idrj   new_gmrA  s         @r=   sequential_splitrI  d  s     :99999IH # #>$ 	MH"	$\

$$$$  $  F H-FL
Mr@   r^   c                      fd| D             S )z:Returns the nodes that match the node_call_back as a list.c                 *    g | ]} |          |S r4   r4   )r;   rj   r=  s     r=   r   z nodes_filter.<locals>.<listcomp>  s(    ;;;TnnT&:&:;D;;;r@   r4   r^   r=  s    `r=   nodes_filterrM    s    ;;;;U;;;;r@   c               #   8   K   t           } da 	 d V  | a d S # | a w xY wNT)_DISABLE_ATEN_TO_ASSERTION_PASS)orig_vals    r=   $_disable_aten_to_metadata_assertionsrR    s?       /H&*#3*2'''('2222s    c                    ddl m}m} t          rd S t          j        j        j        j        t          j        j        j        j	        t          j        j        j        j
        g}| j        j        D ]q}|j        |v rd|j        j        t          j        j        j        j        k    r"|j        d         |j        j        d         k    rX|j        d         j                            d          x}| j                            |          5   || t+          j        ||j                            d          |j                            d          d                    5  | j                            t          j        j        j        j        |j        d         f|j	        |j        |j        d	           d d d            n# 1 swxY w Y   d d d            n# 1 swxY w Y   sd S )
Nr   _node_metadata_hook_set_node_metadata_hookr   r   r   )r   r   r   )dtypedevicelayoutargskwargs)(torch._export.passes._node_metadata_hookrU  rV  rP  r`   opsatentorY  rX  dtype_layoutr]   r^   r9   prev_assert_tensor_metadatadefaultr\  r   r   inserting_before	functoolspartialr   rZ  )r   rU  rV  aten_to_variantsrj   
tensor_vals         r=   $_insert_aten_to_metadata_assert_passrk    sc          
 '  		 		&
   ;***	 EIN$J$RRRIaLDIN1$555 "il/33E:::
GH--d33 ++!)//3y}}]/K/K379==AR3S3S& &  	 	  H**	>F"il_%/%5&0&7&0&7    +                                 s8   AGAF=1G=GGGGG	G	c           	         ddl m}m} ddlm} t
          j        j        j        sd} || t          j
        |d|i                    5  t          |           }|r(t          | |dt          | j                   d	           d d d            n# 1 swxY w Y   t          |            |                                   ||           |_        | |fS )
Nr   rT  )_graph_output_nameszUFile "torch/fx/passes/runtime_assert.py", line 24, in insert_deferred_runtime_assertsr   rW  zexported program: T)export)r^  rU  rV  4torch._functorch._aot_autograd.input_output_analysisrm  r`   _dynamoconfigdo_not_emit_runtime_assertsrg  rh  r   r   r   r]   rk  rg   user_outputs)r   rK   rU  rV  rm  r   r   s          r=   apply_runtime_assertion_passrt    so           YXXXXX=; 11 	 %$#}k.J  
 
 	 	 /r22I /X)LRX)V)VXX	   	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  	-R000 LLNNN#6#6r#:#:O s   	:BBBc                 f    t          | |r|nd           }t          |          dk    r|d         S dS )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                     dS rO  r4   rj   s    r=   rB  znodes_first.<locals>.<lambda>  s    QU r@   r   N)rM  r   )r^   r=  rets      r=   nodes_firstry    s=     uUnnDUDU
V
VC
3xx!||1v4r@   c                 <    t          t          | |                    S )z:Returns the number of nodes that match the node_call_back.)r   rM  rL  s     r=   nodes_countr{    s    |E>22333r@   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.
    r4   )r^   r=  rj   s      r=   	nodes_mapr}    s+    
   tLr@   old_nodenew_nodec                     |                      |           | j                                         | j                            |            dS )z5
    Replace all uses of old_node with new_node.
    N)replace_all_uses_withusersclearr]   
erase_node)r~  r  s     r=   node_replace_r    sH     ""8,,,NNh'''''r@   c                     t          |t          j        j                  rBt	          |d          r4d|j        v r-| j                            d|j        d         i           d S d S d S d S )Nr   r   )rd   r`   ra   r   hasattrr   update)r   rM   s     r=   _update_gm_meta_if_possibler    s|    3,--7C  7   
#(8"45666667 7 7 7 ! r@   call_mod_nodec           
         | j         dk    sJ | j        j        }|J t          | j        t
                    sJ t          || j                  }d |j        j        D             }d |j        j        D             }d |j        j        D             }t          || j	                  D ]6\  }}t          |t          j        j                  sJ t          ||           7|j                            |           5  |D ]}|j                            |          }	|j         dk    rx|	j        }
t!          ||
          r1d}d| }
t!          ||
          r|dz  }d| }
t!          ||
          |
|	_        t#          ||	j        t          ||j                             t          ||	           t%          |          d	k    rSt%          |          dk    rt%          |d	         j	                  dk    sJ |d	         j	        d	         t          t          j        j                  r*j                                         t          |            nt          t*          t,          f          rD ]"}|j                            |d	                    #t1          t+          | j                                                  d
           }t5          |fd           | j                            |            n:t9          dt;                     d          | j                            |            ddd           n# 1 swxY w Y   |                                 |                                 |S )z
    Inline the submodule of the given node into the parent module.
    Note: we only support the case where submodule takes tensors inputs.
    r   Nc              3   0   K   | ]}|j         d k    |V  dS )r   Nr_   r   s     r=   	<genexpr>znode_inline_.<locals>.<genexpr>!  s.      
K
KD$']2J2J42J2J2J2J
K
Kr@   c              3   ,   K   | ]}|j         d v|V  dS ))r   outputNr  r   s     r=   r  znode_inline_.<locals>.<genexpr>"  s8        tw>W/W/W/W/W/W/W r@   c                 (    g | ]}|j         d k    |S )r  r  r   s     r=   r   z node_inline_.<locals>.<listcomp>%  s$    IIItTW5H5Hd5H5H5Hr@   rZ   r   submod_r   c                 B    | j         dk    o| j        t          j        k    S )Nr   )r_   r9   operatorgetitemrw  s    r=   rB  znode_inline_.<locals>.<lambda>L  s"    O!; "8x'77 r@   c                 F    t          | | j        d                            S Nr   )r  r\  )get_item_node
new_outputs    r=   rB  znode_inline_.<locals>.<lambda>R  s$    -%"=#5a#89+ + r@   zUnsupported output type z2. Expect it to be a Node or a list/tuple of Nodes.) r_   r]   owning_modulerd   r9   r   rF   r^   r   r\  r`   ra   Noder  rf  	node_copyr  rI   r   r  r  r)  r(  rH   rM  keysr}  r  NotImplementedErrorr   delete_all_unused_submodulesrg   )r  r   sub_gmphsbodyr  phr   rj   r  new_target_namer   get_item_usersr  s                @r=   node_inline_r    s   
 },,,,			*B>>>m*C00000R-..F
K
KFL.
K
K
KC +  D JIv|1IIIFsM.//  C#ux}-----b#		"	"=	1	1 2: 2: 	* 	*Dx))$//Hw*$$"*/2// 8A&3mmO!"o66 8Q*7A-- ""o66 8 #2HOWVT[-I-IJJJ$))))v;;??v;;!##F1IN(;(;q(@(@(@@*J*ehm44   &&(((mZ8888Ju66 & . .DJNN6!9---- ".,1133448 8" " "      #..}====)stJ/?/?sss   **=999e2: 2: 2: 2: 2: 2: 2: 2: 2: 2: 2: 2: 2: 2: 2:h ##%%%LLNNNIs   8H4L88L<?L<c                 r   t          j        | j                  }|j        d         }dt          j        i}g }|                                D ]X\  }}d t          |j        |          D             }|D ]1}|dk    r	|	                    t          j        ||                     2Yt          j        |          S )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\  c                     g | ]	}|j         
S r4   )r   )r;   as     r=   r   z:_get_torch_jit_trace_forward_signature.<locals>.<listcomp>t  s    MMM1MMMr@   self)
parameters)astparsecoder  r   POSITIONAL_OR_KEYWORDrD   rF   r\  r  inspect	Signature)	rM   ast_modast_func_defarg_type_map
param_listarg_type
param_typearg_name_listarg_names	            r=   &_get_torch_jit_trace_forward_signaturer  d  s     i!!G$+LOL I;<L J , 2 2 4 4 G G*MM0A8(L(LMMM% 	G 	GH6!!g/*EEFFFF	G
 
3333r@   c                 X   t          | t          j        j        t          j        j        f          rOt          |           }t          |j                  t          |          t          |          z   k    s
J d            nt          j	        | j
                  }i  |j        | j        |S )NzyArguments other than POSITIONAL_OR_KEYWORD kinds in forward() are not supported in _get_torch_jit_trace_forward_signature)rd   r`   jitScriptModuleTracedModuler  r   r  r  	signatureforwardbind_partial	arguments)rM   	fake_argsfake_kwargsrl   s       r=   _bind_signature_to_inputsr  }  s    #	.	0FGHH 	-4S99 3>""c)nns;7G7G&GGGGJ HGGG
 ,, Ec	*4DDDr@   c                    |                     |            t          j        d|           }|rW|                    d          |                    d          }}t	          |          ||         k    rt	          |          ||<   d S d S d S )Nr   r   r   )rJ   r   r   r   r   )rP   r   r   r   r|   r   s         r=   _build_cacher    s    NN4H]D))E ,KKNNEKKNNq66N6***%(VVN6""", ,**r@   c           	      ~   g }| j         j        D ]D}|j        dk    r5t          |j        t
          j        j                  r|j        j        dk    ra|j	        \  }}}}|
                    t          | |j                  |f           |
                    t          | |j                  |f           |j        j        dk    rG|j	        d         |j	        dd         }}|
                    t          | |j                  |f           |j        j        dk    r8|j	        \  }	}
}|
                    t          | |	j                  |
|z   f           F|D ]\  }}i }t          t                    }t                      }t          |j         j                  D ]\  }}|t!          |          k     rE||         j        ||j        <   ||         j        x|_        |_        t%          |j        ||           ]t'          ||||j        |j                  |_        t)          |           |                                 dS )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.
    r   condwrap_with_set_grad_enabledr   r   Nmap_impl)r]   r^   r_   rd   r9   r`   r   r   _name_argsr  rF   r   r   r\   r   r   rP   r  r   _name_hoo_subgraph_placeholdersrg   )r   subgraph_ph_tuplesrj   r   
true_graphfalse_graph	cond_argssubgraphr  
body_grapharrayr\  hoo_phsr   r   r   r   s                    r=   r  r    sJ    RT  7o%%*K7+
 +
% { F**8<
5:{I"))72z7H+I+I9*UVVV"))72{7I+J+JI*VWWWW"&BBB $
1tz!""~#"))72x+G+G*MNNNN"j00*.*'
E4"))R!233UT\B  
 0  '#%)4S)9)9"uu
 !566 	 	GAt3w<<&-ajo#*1!*/9	DKTY
CCCC6nj$)TY 		
 	(111! r@   export_graph_signaturerL   c                 	   i }t          |t          j        j                  r-|j        j        D ] }d|j        v r|j        d         ||j        <   !d }	d i }
t          t                    }t                      }t          |||          }t          |          \  }}d |j        D             }t          ||          D ]V\  \  }}}|rLt          |
|||t           t"          j                 d                    fd|D                       z   d           W|j        D ]}|j        t"          j        k    r|j        t"          j        k    rd	}n" |	|j                                                  }t1          j        d
d|          }t          |
|||j        j        t           |j                 |z   d           ||v r||         ||
|j        j                 <   ||= | j        j        D ]+}|j        dk    rt          |
|||j        |j                   ,| j        j        D ]}|j        dk    r|j        |
v sJ |
|j                 x|_        |_        |j        |v rN|j                            d          ||j                 |j        d<   n|j        d         ||j                 k    sJ t          |j        d         t:                    r|j        |j        d         _        |j        |
v r|
|j                 |_        t=          |            |                                  |j        D ]f}|j        j        |
v sJ |
|j        j                 |j        _        |j        t"          j         k    r#|j        |
v r|
|j                 dd         |_        g|j!        D ]\}|j        j        |
v r|
|j        j                 |j        _        |j        tD          j#        k    r|j        |
v r|
|j                 |_        ]tI          |%                                          D ]q}||         }||
v rct          |t          j&                  sI|
|         }||k    r;t1          j'        d|          r&|t           t"          j                  |z   k    r|||<   ||= rdS )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, ...
    r   c                     |                      d          r| t          d          d          } n,|                      d          r| t          d          d          } t          j        dd|           } | S )N
L__self___self_[^a-zA-Z0-9]r   )
startswithr   r   subxs    r=   _strip_namez,placeholder_naming_pass.<locals>._strip_name  sp    <<%% 	"#l##%%&AA\\'"" 	"#g,,..!AF?C++r@   c                 N   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|            )Nr  r   zPytree key of type z not handled for )rd   r&   r   r  r   r   r'   r   r#   rP   rq   r   r  s    r=   _extract_pytree_keyz4placeholder_naming_pass.<locals>._extract_pytree_key  s    a$$ 	TSZZ88AH;'' 	Tqu:::&& 	T6MRT!WWRRqRRSSSr@   c                 P    g | ]#}|j         t          j        k    |j        j        $S r4   )r6   r   
USER_INPUTr   rP   r:   s     r=   r   z+placeholder_naming_pass.<locals>.<listcomp>  s6       9	,,, 	,,,r@   r   c              3   R   K   | ]!} |                                           V  "d S r  )lower)r;   r  r  s     r=   r  z*placeholder_naming_pass.<locals>.<genexpr>  s;      LLa..q117799LLLLLLr@   T)r   r+   r  r   Nr      z
arg(\d+)_1)(rd   r`   ra   r   r]   r^   r   rP   r   r   r\   r  r)   rC   r   r   placeholder_prefixesr   r  joinr6   TOKENr9   r  r   r  r   r_   r   r   r  rg   
CUSTOM_OBJro   r   USER_INPUT_MUTATIONr)  r  re   r   )r   r  rM   r  r  fake_params_buffersrL   custom_metarj   r  r   r   r   combined_argsr   r   user_input_namesarg_path_arguser_input_namer<   	base_namerP   constantr   r  s                            @r=   placeholder_naming_passr    s	   6 #%K#ux+,, =IO 	= 	=D49$$)-8)<DI&  	T 	T 	T  "H%0%5%5N55J .c9kJJM3MBB *6   .11DFV-W-W 
 
)4/ 		&$Y%9:((LLLL8LLLLLM#    '2 ' '9	,,,9	''II#DK006688IF?C;;	"HM +i7	
 	
 	
 	
 ## 4?y3IK/0I&  
 
7m##"nj$)TY	
 	
 	
 	

  , ,7m##9((((&.ty&99DIyK''9==**2*5di*@DIh''9X.+di2HHHHH $)E*,=>> 2(,		% %Y("" +DI $B''' LLNNN '2 4 4x}(((( /I---$+2I2I"4;/3DK&3 0 08=H$$$TX]3DHM9
6664;(;R;R"4;/DK Y^^%%&& $ $T?8Jel%
 %
  ~HD  H]D11 ! 4Y5I JT QQQ&.	(#dO$ $r@   rh   in_placec                 D   |rB|                                  D ]+\  }}t          |d          rt          | |         d           ,| S i }|                                  D ]D\  }}t          |d          r*|                                                                ||<   ?|||<   E|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.
    r   )rD   r  delattrdetachclone)rh   r  r   r   new_state_dicts        r=   remove_proxy_from_state_dictr  s  s      $$&& 	0 	0DAqq'"" 0
1w///$$&& 	& 	&DAqq'"" &$%HHJJ$4$4$6$6q!!$%q!!r@   c                    g }g }| j         j        D ]}|j        dk    rHd|j        v r?|j        d         }|/t	          |t
          j                  r|                    |           Ut          |          dk    rrd|j        v s	d|j        v r`d}d|j        v r|j        d         }nd|j        v r|j        d         }|/t	          |t
          j                  r|                    |           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.
    r   r   Nr   example_value)
r]   r^   r_   r   rd   r`   re   r  r   r   )r   	fake_inps	fake_valsrj   fake_vals        r=   r   r     s    %'I$&I + +7m##(:(:y'H#
8U\(J(J#  ***^^q  ty((ETY,>,>H$)++9_5$)##9U+#
8U\(J(J#  ***I	1222r@   c              #   
  K   t          | j                  }t          | j                  }| j                                         | j                                         	 d V  || _        || _        d S # || _        || _        w xY wr  )r  _state_dict_hooks_state_dict_pre_hooksr  )rM   state_dict_hooksstate_dict_pre_hookss      r=   _disable_load_state_dict_hooksr	    s      ,01F,G,G04S5N0O0O!!!##%%%9 0$8!!! !1$8!8888s   A2 2Br_   r   c                     t           j                            |                                 t           j        j        j                  pt           j        j        j        | j        v S r  )r`   r   %_dispatch_has_kernel_for_dispatch_keyrP   DispatchKeyCompositeImplicitAutograd
py_kernelsr  s    r=   
_is_cia_opr    sK    66GGIIux+E	
 	
 	K 89R]J	r@   c                 >    t          |           ot          |           S r  )_check_valid_to_preserver  r  s    r=   _is_preservable_cia_opr    s    #B'':JrNN:r@   c                 d    |                                                      d          d         dk    S )N::r   r`  )rP   rE   r  s    r=   _is_aten_opr    s&    7799??4  #v--r@   c                 "    t          |            S r  )r  r  s    r=   _is_custom_opr    s    2r@   c            	         t           j                            d          } | D ]}t          |                    d                    \  }}|                    d          }t          |          dk    st          |          dk    sJ |d         }d}t          |          dk    r|d         }t          t          t          t           j        |          |          |          }dS )	z
    Utility function to query C++ dispatcher to get the all
    possible CIA ops and populate them into torch.ops namespace
    r  r  rA   r   r   r   re  N)r`   r   ,_dispatch_get_registrations_for_dispatch_keyr(  rE   r   rF   r_  )cia_opsr_   	namespaceop_name
split_listop_overload_namer   s          r=   _materialize_cpp_cia_opsr    s    
 hCC# G
  
W 
W"288D>>22	7]]3''
:!##s:!';';';;Q-$z??a)!}GGEIy997CCEUVV
W 
Wr@   c                      t           S )z]
    This is an special marker that tells our infra that we shouldn't decompose this op.
    )NotImplementedr[  s     r=   _special_op_to_preserve_ciar"    s
     r@   op_overloadc                 H   ddl m}  ||           rdS | t          j        v rdS t	          | d          sdS t          d | j        j        D                       }|dk    p| j        j        }|rdS t          j
                            |                                           sdS dS )Nr   )#_should_decompose_because_unsafe_opF_schemac                      g | ]}|j         	|S r  )
alias_info)r;   r   s     r=   r   z,_check_valid_to_preserve.<locals>.<listcomp>  s    NNNqQ\5M5M5M5Mr@   T)torch._decompr%  r   metadata_fnsr  r   r&  r  
is_mutabler`   r   _dispatch_has_kernelrP   )r#  r%  r(  is_mutating_or_aliasings       r=   r  r    s    AAAAAA**;77 u&333u;	** uNNK'1NNN J )AoO1D1O u8(()9)9););<< u4r@   r   )maxsizec                  >    t          t          j        j                  S r  )(_collect_all_valid_cia_ops_for_namespacer`   r_  r`  r4   r@   r=   -_collect_all_valid_cia_ops_for_aten_namespacer1    s    3EINCCCr@   op_namespacec                     t                       t                      }| D ]]}t          | |          }|                                D ]6}t          ||          }t	          |          r|                    |           7^|S r  )r  r\   rF   	overloadsr  rJ   )r2  r  r_   	op_packetoverloadr#  s         r=   r0  r0    s      eeG ) )L"--	!++-- 	) 	)H!)X66K%k22 )K(((	) Nr@   c                  H   t                      } t          j        j        D ]}|dk    rht	          t          j        |          sJ t          t          j        |          }t          |t          j        j                  r| t          |          z  } p| t                      z  } | S )a  
    This is an util function that gets the all CIA functional ops.

    The algorithm is in 2 steps:
      1. We first query C++ dispatcher to get the list of CIA ops
         and then we call getattr on torch.ops.aten to lazily populate
         them.

      2. Sometimes, handful of ops have CIA registered in python dispatcher
         but not on the C++ side, these can't be caught at the first step.
         So we walk again to get the final list.

    Note that the output of this function should never be modified
    r`  )r\   r`   r_  _dirr  rF   rd   r   _OpNamespacer0  r1  )r  op_namespace_namer2  s      r=   _collect_all_valid_cia_opsr;    s     eeG"Y^ G G&&59&788888"59.?@@L,
(?@@ RCLQQQDFFFGGNr@   c                     t           j        j        j        }|| j        v r7t          | j        |         t           j        j                  s| j        |         S d }t          j        ||           S )Nc                     |d         }|d= t           j        j        j        }t           j                            |                                t           j        j        j                  r |j        |g| R i |S t          d| d          )Nkernel	Expected z) to have CompositeImplicitAutograd kernel)r`   r   r  r  r  rP   _op_dkAssertionError)r\  r]  r>  dks       r=   _special_op_to_decompose_ciaz9_get_decomp_for_cia.<locals>._special_op_to_decompose_ciaC  s    !8 X!;899KKMM58/I
 
 	 !6=5d555f555 MFMMM  r@   )r>  )r`   r   r  r  r  rd   rg  rh  )r_   rB  rC  s      r=   _get_decomp_for_ciarD  8  sn     
		7B	R]:bmB.?AU#V#V}R     9"EEEEr@   c               #   .  K   t           j        j        } t           j        j        }	 dt           j        _        dt           j        _        d V  | t           j        _        |t           j        _        d S # | t           j        _        |t           j        _        w xY wrO  )r`   compiler_is_compiling_flag_is_exporting_flag)old_compiling_flagold_exporting_flags     r=   _compiling_state_contextrK  U  s{      ::?,0),0),>),>))) -?),>)>>>>s   &A0 0$Br   c                 |   i t          |                    d                    t          |                    d                    }i }i }|                                D ]Z\  }}t	          |          |v r|t	          |                   }n)|                     |d          }||t	          |          <   |||<   [|S )NF)r   T)static_shapes)r  r   r   rD   idfrom_tensor)r   rM   params_buffersfaked_params_buffersmemor   rQ   fake_tensors           r=   _fakify_params_buffersrT  b  s    
s##U#;;
<
<
s  % 88
9
9N
 "$D$**,, 0 0
Ue99r%yy/KK#//T/JJK)DEO$/S!!r@   c           	      J   
 t           t          j        j                  sJ ddl} G 
 fdd|j                  
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}||} j        dz    j        z   }d }
fd}t           |||||           dt          t                   ffd}	t           |	           dS )aF  
    Registers a module as a valid input type for :func:`torch.export.export`.

    Args:
        mod: the module instance
        serialized_type_name: The serialized name for the module. This is
        required if you want to serialize the pytree TreeSpec containing this
        module.

    Example::

        import torch


        class Module(torch.nn.Module):
            def __init__(self):
                super().__init__()
                self.linear = torch.nn.Linear(3, 3)

            def forward(self, x):
                return self.linear(x)


        torch._export.utils.register_module_as_pytree_node(InputDataClass)


        class Mod(torch.nn.Module):
            def forward(self, x, m):
                return m(x) + x


        ep = torch.export.export(Mod(), (torch.randn(3), Module()))
        print(ep)

    r   Nc                   2     e Zd Z fdZd ZfdZ xZS )=register_module_as_pytree_input_node.<locals>.PrototypeModulec                      t                      j        |g|R i | t          |t          j        j                  sJ t          | d          rJ | _        d S )N
_proto_cls)super__init__rd   r`   r   r   r  rY  )r  mr\  r]  	__class__r	  s       r=   r[  zFregister_module_as_pytree_input_node.<locals>.PrototypeModule.__init__  se    EGGQ0000000a11111t\22222!DOOOr@   c                 "    | j         |j         k    S r  )rY  )r  others     r=   __eq__zDregister_module_as_pytree_input_node.<locals>.PrototypeModule.__eq__  s    ?e&666r@   c                 *      |                       S r  r4   )r  rR  PrototypeModules     r=   __deepcopy__zJregister_module_as_pytree_input_node.<locals>.PrototypeModule.__deepcopy__  s    "?4466***r@   )__name__
__module____qualname__r[  r`  rc  __classcell__)r]  rb  r	  s   @r=   rb  rW    sf        	" 	" 	" 	" 	" 	"	7 	7 	7	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+r@   rb  r  r1   c                 .   t          |                                           }t          |                                           }i ||}t          |                                          t          |                                           |           gfS r  )r  r   r   r)  r   r  )r  r   r   rP  rb  s       r=   r  z@register_module_as_pytree_input_node.<locals>.default_flatten_fn  s     4 4 6 677S..0011>,>>N))++,,$$&&''OC  /
 
 	
r@   r   r  c           	         |\  }}|
 |            t          d           |            }	J  	|          \  }}dt          j        j        ffdt	          d t          | |          D                       rlt          j        j        j                            |t          t          ||                     dd          5   |          }d d d            n# 1 swxY w Y   n|}|S )Nz!Module has been garbage collectedrM   c                     t          j         |           }d | j                                        D             |_        |                                D ]\  }}t	          || |                      |S )Nc                 b    i | ],\  }}t          j         |          t          j         |          -S r4   )copyr   s      r=   
<dictcomp>zkregister_module_as_pytree_input_node.<locals>.default_unflatten_fn.<locals>.copy_module.<locals>.<dictcomp>  s.    XXX41aDIaLL$)A,,XXXr@   )rl  __dict__rD   named_childrenrI   )rM   rx  rP   childcopy_modules       r=   rq  zWregister_module_as_pytree_input_node.<locals>.default_unflatten_fn.<locals>.copy_module  sv    )C..CXX3<CUCUCWCWXXXCL"1133 7 7eT;;u#5#56666Jr@   c              3   $   K   | ]\  }}||uV  d S r  r4   )r;   r   os      r=   r  zUregister_module_as_pytree_input_node.<locals>.default_unflatten_fn.<locals>.<genexpr>  s*      ==daqz======r@   T)tie_weightsstrict)
rq   r`   r   r   anyr   utils	stateless_reparametrize_moduler  )
r   r  r  refr  r  r   rx  rq  r
  s
           @r=   r  zBregister_module_as_pytree_input_node.<locals>.default_unflatten_fn  sX   !
C;##%%-BCCCcee%%%!z#	1	UX_ 	 	 	 	 	 	 ==c&)&<&<===== 	)??T#j&1122T @   ' ' "k#&&' ' ' ' ' ' ' ' ' ' ' ' ' ' '
 C
s   CC!$C!c                 b     |           \  }^}}d t          ||          D             |g|fS )Nc                 6    g | ]\  }}t          |          |fS r4   r  r   s      r=   r   z^register_module_as_pytree_input_node.<locals>.default_flatten_fn_with_keys.<locals>.<listcomp>  r!  r@   r"  )r  r  r  r\  r
  s       r=   r$  zJregister_module_as_pytree_input_node.<locals>.default_flatten_fn_with_keys  sQ    )3C&	&JJJs:y/I/IJJJM
M
 
 	
r@   rA   c                 Z    | ^}}t          j        |gd gt          |          z            S r  )jsondumpsr   )r  r  r   s      r=   r  zAregister_module_as_pytree_input_node.<locals>.to_dumpable_context  s/    qz44D6CFF?4555r@   c                     t          j        |           } t          j                                                  |d<   |S r  )r~  loadsr`   r   r   )dumpablesrb  s     r=   r  zCregister_module_as_pytree_input_node.<locals>.from_dumpable_context  s6    Jx  ux0011!r@   r%  c                 >     |           \  }}||j         k    sJ |S r  )r  )r  r<   flatsr  r
  s       r=   default_flatten_fn_speczEregister_module_as_pytree_input_node.<locals>.default_flatten_fn_spec  s,    #Cw$,&&&&r@   )
issubclassr`   r   r   weakrefrz  r   r(  r)  r    r   re  rf  r   r   )r	  r  r  r  r$  r  r  r  r  r  rb  r
  s   `         @@r=   $register_module_as_pytree_input_noder  w  s   H c58?+++++NNN+ + + + + + + +'+ + + +
 
d3i.@(A 
 
 
 
 
 
Xc] W       8
# 
%S	78J2K 
 
 
 
 
 
 $J'L>C/#2BB6 6 6    
 19/3   d3i      
 !    r@   c                 B    t          |            t          |            d S r  )r   r   )r	  s    r=   &deregister_module_as_pytree_input_noder    s$    C   #C(((((r@   c                     t          | t          j        j                  sJ d|  d            t          |t          j        j                  sJ d| d            | j        |_        | j        |_        d S )Nr?  z to be a nn.Module)rd   r`   r   r   _parametersrG   )srcdsts     r=   _sync_stater     s      + + +3***+ +    + + +3***+ +  oCO<CLLLr@   c                  @    | r| ^}}|D ]}t          ||           dS dS )z
    Sync state between exported modules corresponding to wrapped methods.
    This might be necessary after serializing/deserializing due to copying.
    N)r  )wrapped_method_modulesr\  other_msother_ms       r=   
sync_stater    sK    
  $-H 	$ 	$G7####$ $	$ 	$r@   c                        e Zd Z fdZ xZS )_WrappedMethodc                     t                                                       t          |j        |            || _        d S r  )rZ  r[  r  __self__r  )r  methodr]  s     r=   r[  z_WrappedMethod.__init__  s6    FOT***r@   )rd  re  rf  r[  rg  )r]  s   @r=   r  r    s8                r@   r  c                 Z    t          |           sJ d|  d            t          |           S )z
    Wrap a method as a module so that it can be exported.
    The wrapped module's forward points to the method, and
    the method's original module state is shared.
    r?  z to be a method)r   r  )r  s    r=   wrap_methodr  %  sK       + +*6***+ +  &!!!r@   )r1   r   )rl   r   )rs   r   rt   r   )Fr  )NN)r1   N)r#  r   )r_   r   )r  rl  r  rg  r  r~  r   r  r   collectionsr   collections.abcr   
contextlibr   r   r   typingr   r	   r
   r   r   r`   torch._guardsr   torch._subclasses.fake_tensorr   r   #torch._subclasses.functional_tensorr   torch.fx._utilsr   "torch.fx.experimental.proxy_tensorr   torch.fx.passes.runtime_assertr   rB   r   
torch._opsr   torch.exportr   torch.export.graph_signaturer   r   r   r   torch.fx._pytreer   r   torch.utils._pytreer   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r  	PARAMETERr7   rn   r  r  r  rP  rV   ra   r   rk   rr   rw   r  r   r   r   r   r   r   r\   boolr   r   r   r   r)  r  r  r   r+  r/  r   r2  r4  re   r6  r9  r<  rI  rM  rR  rk  rt  ry  r{  r}  r  r   r  r  r  r  r  r  r  r  r  _subclassesrS  r   r	  r  r  r  r  r  r"  r  	lru_cacher1  r   r9  r0  r;  rD  rK  rT  r  r  r  r  r  r  r4   r@   r=   <module>r     s   



              				 # # # # # # $ $ $ $ $ $ % % % % % % ' ' ' ' ' ' ' ' @ @ @ @ @ @ @ @ @ @ @ @ @ @  * * * * * * D D D D D D D D @ @ @ @ @ @ ? ? ? ? ? ? K K K K K K J J J J J J  BHHHHHH'''''',,,,,,AAAAAA Q Q Q Q Q Q Q Q Q Q                                    $ "dt&OW  #(    <%		% % % %4	   (#.D    6'(< 6'c3h 6' 6' 6' 6'r  .)!%c3h)) $) 
	) ) ) )8$ux3 $ $ $ $* !% %38n%cN% C% 	%
 % % % % %P/ /S / / / /0 [
 [
#u|#$[
	[

 [
 }[
 
[
 [
 [
 [
|)UX]+)	) ) ) )\ )-,04
 +/9==A$4 4 4	c4%4 =)4
 #3-4 ""564 $$9:4 4 
4 4 4 4nE' Eux} E E E E E
(- eh !    B( B B$ B B B B
(- el   &RR
(-R 
R R R R
(- el   $ehm_eEHM44G.HHI X   ><UX]+ <UX]@S < < < <
 3 3 3-UX-A -d - - - -`!UX%9 ! ! ! !J 04
 

ehm
 
 
 
4tEHM* 4s 4 4 4 4
T%(-( T%(-=P    (EHM (UX] (t ( ( ( (7EH$8 7ux 7SW 7 7 7 7L L(58;O2P L L L L^4 4GDU 4 4 4 42E E E&, , ,-(< - - - - -`g$g$2g$ 
g$ CH~g$ 
g$ g$ g$ g$TT T d    *33e+:;3 3 3 3< 	9 	9 	9 	9 	9> d    ;~ ;$ ; ; ; ;.N .t . . . .n     W W W W.     4 QDs>7J D D D  D*)   "C$7    8F F F F: 	? 	? 	?  	  
#uU\58#556
67       *Ad58?.C A A A A AH)UX_0E )$ ) ) ) )
     "$ $ $    UX_   	" 	" 	" 	" 	"r@   