U
    yh                     @   s  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
mZmZmZmZmZmZ d dlZd dlm  mZ d dlm  mZ d dlmZ d dlmZ d dlmZmZm Z m!Z!m"Z"m#Z# d d	l$m%Z% d d
lm&Z&m'Z' ddddgZ(G dd deZ)d@eej*ej+f ej,j-e.e)e/dddZ0G dd dej,j-Z1G dd de j2Z3G dd dej,j-Z4dAeee3 e4dddZ5ejj6ddddZ7dd Z8e.e.e.dd d!Z9ej,j-ej,j-d"d#d$Z:ej,j-e.d%d&d'Z;ej,j-ejj<d%d(d)Z=ej,j-ejj<d%d*d+Z>ej,j-e.d,d-d.Z?ej,j-e.ej,j-d/d0d1Z@G d2d3 d3ZAejj6e4d4d5d6ZBdBej,j-ee.eCf e.d8d9d:ZDej,j-ee.ee. f ee. d;d<d=ZEd>d? ZFdS )C    N)defaultdict)deepcopy)Enum)AnycastDictListOptionalSetTupleUnion)FakeScriptObject)reorder_kwargs)ConstantArgumentExportedProgram	InputKindModuleCallSignatureSymIntArgumentTensorArgument)is_fx_tracing)
GetAttrKeySequenceKeyInterpreterModuleUnflattenedModule	unflattenFlatArgsAdapterc                   @   s   e Zd ZdZdZdZdS )	_AttrKindZ	parameterbufferconstantN)__name__
__module____qualname__	PARAMETERBUFFERCONSTANT r%   r%   H/var/www/html/venv/lib/python3.8/site-packages/torch/export/unflatten.pyr      s   r   T)from_obj	to_moduletarget	attr_kind
persistentc           	      C   s   | d^ }}|D ]2}t||d }|d krBtj }t||| |}q|tjkrrt| tjj	sdt
|||  nj|tjkrt| tjst
|j|| |d n>|tjkrt| trt
dt| tjtjfst
t|||  d S )N.)r+   z2FakeScriptObject should only exist during tracing.)splitgetattrtorchnnModulesetattrr   r"   
isinstance	ParameterAssertionErrorZregister_parameterr#   TensorZregister_bufferr$   r   ScriptObject)	r'   r(   r)   r*   r+   prefixfielditemtr%   r%   r&   _assign_attr%   s6    



 r<   c                       s:   e Zd ZdZejjd fddZdd Zdd Z	  Z
S )	r   zA module that uses torch.fx.Interpreter to execute instead of the usual
    codegen that GraphModule uses. This provides better stack trace information
    and makes it easier to debug execution.
    graphc                    s   t    || _| | j_d S N)super__init__r>   Zowning_module)selfr>   	__class__r%   r&   rA   O   s    
zInterpreterModule.__init__c                 O   s   | j d k	stdtj r(| j ||S |rt|}| jt|d  }|D ]}||krJ|||  qJt|t|ksztt|t| jkstt	|}tj
j| | jdj|ddiS d S )Nz&Didn't finalize this InterpreterModuler=   enable_io_processingF)graph_moduler5   r/   compilerZis_dynamo_compilinglist	arg_nameslenappendtuplefxInterpreterr>   run)rB   argskwargsarg_listZkwarg_namesZ
kwarg_namer%   r%   r&   forwardW   s"    
zInterpreterModule.forwardc                 C   sP   t j| | j| jd< | j  g | _| jjD ]}|jdkr.| j	|j
 q.d S )NrF   placeholder)r/   rM   ZGraphModuler>   __dict__ZlintrI   nodesoprK   r)   rB   noder%   r%   r&   finalizet   s    

zInterpreterModule.finalize)r   r    r!   __doc__r/   rM   GraphrA   rS   rZ   __classcell__r%   r%   rC   r&   r   I   s
   c                   @   s6   e Zd ZdZejejejee	 ee	 dddZ
dS )r   zN
    Adapts input arguments with ``input_spec`` to align ``target_spec``.
    )target_spec
input_spec
input_argsreturnc                 C   s   dS )z=NOTE: This adapter may mutate given ``input_args_with_path``.Nr%   )rB   r^   r_   r`   r%   r%   r&   adapt   s    zFlatArgsAdapter.adaptN)r   r    r!   r[   abcabstractmethodpytreeZTreeSpecr   r   rb   r%   r%   r%   r&   r      s   c                       s:   e Zd Zd	eee d fddZdd Zdd Z  Z	S )
r   N)export_moduleflat_args_adapterc           !         s  t    |jjd k	rtddd |jD }|d dks>tt|j}t|j| _t	j
 | _t|j| _|| _d| _t|| j t||  |j| _g | _|j}t }i }| jjD ]T}|| }	t|	|krt	j|	 |t|	< t|t|	 | |tjd || qt| jj}
t }i }| jjD ]x}||
krFd}|j| }nd}|| }t||krt| |f|t|< t|t| d | |tj |d	 || q(|! D ]\}}||ks||krʐqd}t||kst"|t	jjsd}|r6t||kr|df|t|< t|t| d | |tj dd	 n4t||krP||t|< t|t| | |tjd qi }|j! D ]X\}}t||krt"|t	j#r| }||t|< |t| }t|| |tj$d q|t%t&t }fd
d}t }| jj'D ]}|j(t)jks(|j(t)j kr|j*rt+|j,ds:tt"|j-t.sLt|t|j|j- |j,j/|j- ||j- ||j- n|j(t)j kr|j*r|j(t)j0ks|j(t)j1krt+|j,dstt"|j-t.st|t|j|j- |j,j/|j- ||j- q|j! D ]Z\}}||krt|ks:tdt| d \}}|t||| ||j- q|j! D ]J\}}||krxt|krqxt| d \}}|t||| qxi 2 D ],}dd |D }|D ]\}}||< qqt3| g   fdd  | g  dd | jj4D | _5d| _6dd t7|D } | j8ddD ] \}}|| krZt9| | |< qZt:| |  dd | j8ddD t&| ; kstd S )Nz%Unflattening on JointExportModule NYIc                 S   s   g | ]
}|j qS r%   )fqn.0entryr%   r%   r&   
<listcomp>   s     z.UnflattenedModule.__init__.<locals>.<listcomp>r    F)r*   T)r*   r+   c                    s    |  }| ||f d S r?   )rK   )obj_idZ	node_nameZtarget_name	name_list)
consts_mapr%   r&   add_to_consts_map  s    z5UnflattenedModule.__init__.<locals>.add_to_consts_mapnamez?Constants should be either aliased or appear in graph signaturec                 S   s   g | ]}|d  qS    r%   )rj   r;   r%   r%   r&   rl   P  s     c                    s   t | drd| jjD ]P}|jdkr|jkrt fdd|j D rt|j d  d| j q|  D ]\}} | |  qld S )Nr>   rT   c                 3   s(   | ] }| d dt   kV  qdS )r,   N)r-   rJ   )rj   rh   scoper%   r&   	<genexpr>c  s   zJUnflattenedModule.__init__.<locals>.check_module_inputs.<locals>.<genexpr>z was not sunk into the module z which has the graph: )	hasattrr>   rV   rW   rr   anyr5   Znamed_childrenrK   )modulerv   rY   rr   submod)check_module_inputsinputs_to_stateru   r&   r|   W  s     

z7UnflattenedModule.__init__.<locals>.check_module_inputsc                 S   s   g | ]}|j d kr|qS rT   rW   rj   rY   r%   r%   r&   rl   v  s    
 c                 S   s   i | ]\}}||qS r%   r%   )rj   irh   r%   r%   r&   
<dictcomp>{  s      z.UnflattenedModule.__init__.<locals>.<dictcomp>)Zremove_duplicatec                 S   s   g | ]\}}|qS r%   r%   )rj   rh   _r%   r%   r&   rl     s     )<r@   rA   graph_signatureZbackward_signature
ValueErrormodule_call_graphr5   r   r>   r/   rM   r\   rg   adapted_inplace_buffer_mutations_outline_submodulesrange_constraintsZequality_constraints
state_dictset
parametersidr0   r4   cloner<   r   r"   addnon_persistent_buffersbuffers	constantsr#   itemsr3   r6   r$   r   rH   Zinput_specskindr   r+   rx   argr)   strrr   ZCONSTANT_TENSORZ
CUSTOM_OBJvalues_sink_paramsrV   input_placeholderscheck_input_constraints	enumeratenamed_modulesrJ   _reorder_submoduleskeys)!rB   rf   rg   Zfqn_listZexport_graphr   Zassigned_paramsZid_to_paramrr   paramr   Zassigned_buffersZid_to_bufferr+   r   ZtensorZ	is_bufferZid_to_constrh   r   Z	_constantZconsts_targetsrq   Zadded_params_bufferssZ
const_nameconstZph_namer   Znode_targettargetsn	fqn_orderrC   )r|   rp   r}   r&   rA      sD   




 



	
  


  





zUnflattenedModule.__init__c                 C   sF   |   D ]8\}}t|d  t|drt|jtjjrt|j qd S )N:r>   )r   printrx   r3   r>   r/   rM   r\   )rB   rh   modr%   r%   r&   _print_graph  s    zUnflattenedModule._print_graphc                 O   s  | j d j}t||j}t||f\}}dd |D }t r~tjj	| | j
dj|ddi}t|trzt|dkrz|d S |S ||jkr| jstd| d	d
|j  | jd krtdnV| jstd | jj|j||d}d| _t||jjkrtdt| d|jj | jrXddlm}	 | jdkrDdd |D }
n|}
|	| j|
| j tjj	| | j
dj|ddi}t||jS )Nr   c                 S   s   g | ]}|d  qS rs   r%   )rj   xr%   r%   r&   rl     s     z-UnflattenedModule.forward.<locals>.<listcomp>r=   rE   Frt   zGInput treespec does not match with exported module's: 
Input treespec: z. zExported module treespec: zeThere is no flat args adapter sepcified. Are you sure you are calling this with the right arguments? z5Adapting flat arg to match exported module's treespec)r^   r_   r`   Tz<Flat args adaption failed, number of args mismatch Adatped: z 
Exported module: )"_check_input_constraints_for_graphc                 S   s$   g | ]}t d dtddf|fqS )r   )idxz<unknown location>)rr   )r   r   rj   r   r%   r%   r&   rl     s   )r   	signaturer   in_specre   Ztree_flatten_with_pathr   r/   rM   rN   r>   rO   r3   rL   rJ   r   r   rg   	TypeErrorrb   Z
num_leavesr   Ztorch._export.utilsr   r   r   tree_unflattenout_spec)rB   rP   rQ   r   Zreordered_kwargsZflat_args_with_pathr   	flat_args
return_valr   Znew_flat_args_with_pathZtree_outr%   r%   r&   rS     sn    


  zUnflattenedModule.forward)N)
r   r    r!   r   r	   r   rA   r   rS   r]   r%   r%   rC   r&   r      s     o)rz   rg   ra   c                 C   s
   t | |S )a  Unflatten an ExportedProgram, producing a module with the same module
    hierarchy as the original eager module. This can be useful if you are trying
    to use :mod:`torch.export` with another system that expects a module
    hierachy instead of the flat graph that :mod:`torch.export` usually produces.

    .. note:: The args/kwargs of unflattened modules will not necessarily match
        the eager module, so doing a module swap (e.g. :code:`self.submod =
        new_mod`) will not necessarily work. If you need to swap a module out, you
        need to set the :code:`preserve_module_call_signature` parameter of
        :func:`torch.export.export`.

    Args:
        module (ExportedProgram): The ExportedProgram to unflatten.
        flat_args_adapter (Optional[FlatArgsAdapter]): Adapt flat args if input TreeSpec does not match with exported module's.

    Returns:
        An instance of :class:`UnflattenedModule`, which has the same module
        hierarchy as the original eager module pre-export.
    )r   )rz   rg   r%   r%   r&   r     s    r>   ra   c              
      s  t tt| j}|jdkr*t|jdks.t|jd }|j}|dt| }dd |j	
 D }dd | jD }|D ]~}||j }	||	 }
||
 }| |< | dtjjj||f |j
 D ]\}}| j|< qW 5 Q R X |  fd	d
 qvt|t|d }|f|_dS )a  Transform buffer mutations from their functionalized form into a copy_
    node in the graph.

    Functionalization represents buffer mutation by passing the buffer as an input and output. So for example, the eager code:
        def forward(self, x):
            self.buffer += x
            return x * x

    Will become a graph that looks like:
        def forward(self, buffer, x):
            mutated_buffer = aten.add(buffer, x)
            mul = aten.mul(x, x)
            return (mutated_buffer, mul)

    We want to inplace this into something that looks like the original eager code:
        def forward(self, buffer, x):
            mutated_buffer = aten.add(buffer, x)
            buffer.copy_(mutated_buffer)
            mul = aten.mul(x, x)
            return (mul,)
    outputrt   r   Nc                 S   s   i | ]\}}||qS r%   r%   )rj   kvr%   r%   r&   r     s      z-_inplace_buffer_mutations.<locals>.<dictcomp>c                 S   s   i | ]}|j d kr|j|qS r~   )rW   rr   r   r%   r%   r&   r     s    
  call_functionc                    s   |  k	S r?   r%   )r   new_noder%   r&   <lambda>      z+_inplace_buffer_mutations.<locals>.<lambda>)nextiterreversedrV   rW   rJ   rP   r5   Zbuffers_to_mutateZinputs_to_buffersr   rr   inserting_aftercreate_noder/   ZopsZatenZcopy_metareplace_all_uses_withrL   )r>   r   Zoutput_nodeZreturn_argsZmutation_node_to_bufferZ	mutationsZbuffers_to_inputsZinput_name_to_nodeZmutationZbuffer_nameZ
input_nameZ
input_noder   r   Zuser_outputsr%   r   r&   r     s4    

  r   c                 C   s$   t | t |k o"|dt |  | kS )z2Check whether `candidate` is a prefix of `target`.N)rJ   )	candidater)   r%   r%   r&   
_is_prefix#  s    r   )
parent_fqn	child_fqnra   c                 C   s`   | dkr|S |  d}| d}|d t| |ksJtd| d|  dd|t|d  S )Nrm   r,   zChild module 'z(' is not a descendant of parent module '')r-   rJ   r5   join)r   r   Zparent_splitZchild_splitr%   r%   r&   _compute_accessor(  s    

r   )r   yc                 C   s0   t jjtddd}|| j||jks,td S )Nr   c                    s   g }i  t d fdd}t| jD ]\}}dd t||jD }|dd t||j D 7 }|jdkrt|j	nd}|
| d	|j d
| dd| d | t|< q$d|S )N)ra   c                    s*   t | tjjr"dt t|   S t| S )N%)r3   r/   rM   Noder   r   )r   Z	nodes_idxr%   r&   arg_dump;  s    z?_verify_graph_equivalence.<locals>.graph_dump.<locals>.arg_dumpc                 S   s   g | ]}t |qS r%   )r   r   r%   r%   r&   rl   A  s     zA_verify_graph_equivalence.<locals>.graph_dump.<locals>.<listcomp>c                 S   s   g | ]\}}| d | qS )=r%   )rj   keyvaluer%   r%   r&   rl   B  s   r   rm   z: [z](z, )
)r   r   rV   re   Ztree_maprP   rQ   r   rW   r)   rK   r   r   )r>   retr   r   rY   Z	args_dumpr)   r%   r   r&   
graph_dump7  s    *z-_verify_graph_equivalence.<locals>.graph_dump)r/   rM   r\   r   r>   r5   )r   r   r   r%   r%   r&   _verify_graph_equivalence6  s    r   )gmra   c                 C   s8   d}t | d| r|d7 }qd| }t| || |S )Nr   Z_spec_rt   )rx   r2   )r   specr   rr   r%   r%   r&   	_add_specN  s    

r   c                 C   s*   t | |}| j|}| jtj||fS r?   )r   r>   get_attrr   	fx_pytreeZtree_flatten_spec)r   rY   r   rr   	spec_noder%   r%   r&   _generate_flattenW  s    
r   c                 C   s*   t | |}| j|}| jtj||fS r?   )r   r>   r   r   re   r   )r   rV   r   rr   r   r%   r%   r&   _generate_unflatten]  s    
r   )r   r)   c                 C   sX   | d^ }}|D ]6}t| |d }|d kr2 d S t|tjjsF d S |} qt| |d S )Nr,   )r-   r.   r3   r/   r0   r1   )r   r)   r8   r9   r:   r{   r%   r%   r&   _get_submodulec  s    r   )r   r)   module_to_addc                 C   sl   | d^ }}|D ]F}t| |d }|d krBtj }t| || t|tjjsV dS |} q| || d S )Nr,   F)r-   r.   r/   r0   r1   r2   r3   Z
add_module)r   r)   r   r8   r9   r:   r{   r%   r%   r&   _add_submodulet  s    
r   c                   @   sf   e Zd Zdeeef eejj	 dddZ
dd Zdd Zd	d
 Zdd Zdd Zdd Zdd ZdS )_ModuleFrameN)r   rz   c
              	      st  |_ |_|_|_|_|_|_|_d_jd _	|	d k	rR|	_
nttj _
jjkr~jj _nd _j
jj< j
j_i _i _d _|d k	rt|j	j	}
t|j
|
jd kr܈j
nj |j|
_|j	}|d k	rpjd k	rp|jjdks&t|jjd }|jjd }|jd ksNt|jd k	s^tjd  g }t|jD ]}|j d|  qzi }|jD ]}j |||< qt!j
t"||f|j}t#|j$D ]t\}}jj%dt&j'||ft(|t)s
|j*nd| d	}t(|t)r(qt++j|j* j,|_,|jj|j* < qW 5 Q R X jj-j g }|j$D ]X}t(|t)r|j.d kr|d  n.t(|t/t0fst|j1j|j*  qzt2jj
||j}jj3t&j'|df jj3t&j'|df fd
dt|jD }fdd|jD }W 5 Q R X jd k	s\tt"|j_4|j_5d S )NF   r   rt   Z_positional_arg_r   Z
_constant_)rW   r)   rP   rr   c                    s"   g | ]}j jtj |fqS r%   parentr>   r   operatorgetitem)rj   r   )	args_noderB   r%   r&   rl     s   z)_ModuleFrame.__init__.<locals>.<listcomp>c                    s$   i | ]}|j jtj |fqS r%   r   )rj   r   )kwargs_noderB   r%   r&   r     s     z)_ModuleFrame.__init__.<locals>.<dictcomp>)6
flat_graphrV   
seen_nodesseen_modulesr   module_stack	module_idr   verboserh   rz   r   r/   rM   r\   cached_graph_moduler>   node_mapnode_to_placeholderparent_call_moduler   r   call_modulegetr   Znum_childrenr5   Zchildren_specscontextr   rangerK   rT   r   rL   r   inputsr   r   r   r3   r   rr   copyr   inserting_beforer   r   r   remap_inputr   r   rP   rQ   )rB   r   rV   r   r   r   r   r   r   rz   accessorr   Z	args_specZkwargs_specZ	arg_nodesr   Zkwarg_nodesrr   r   r   Zflat_arg_nodeZinput_nodesinputZinputs_noder%   )r   r   rB   r&   rA     s    
	



 
  z_ModuleFrame.__init__c              	   C   sr   | j dkstd| d|j| jks*t| jd  | jj|j|jd}W 5 Q R X t|j	|_	|| j
|< d S )Nrm   zCannot add placeholder z to root module)Z	type_expr)rh   r5   r>   r   r   rT   rr   typer   r   r   )rB   r   Zplaceholder_noder%   r%   r&   add_placeholder  s    z_ModuleFrame.add_placeholderc                 C   sb   |j | jkst|| jkr$| j| S || jkrX| | | jd k	rX| jd| j	| | j| S )Nr   )
r>   r   r5   r   r   r  r   Z
insert_argr   r   )rB   r   r%   r%   r&   r     s    




z_ModuleFrame.remap_inputc                    s  g } j  j}|d k	r jd k	r|jD ]4}t|ttfrP| j	|j
  q*td| q*t jt fdd|D |j}t jj j|j}|}nfg } j D ]:}|jD ].}|j
 j	kr|| | j|   qqq j}t|dkr|d }t|ttjjfst j| |d kr4d S t|tjjrP|jdndd |D |jd< t|dkr|d kr| jj|d < nDt|D ]:\}	}
tj||	 j }|
jd|jd< | jj|
< q j!d k	rt" j! j d S )	Nz'Unsupported data type for output node: c                 3   s    | ]} j  j|j  V  qd S r?   )r   r   rr   )rj   r   rB   r%   r&   rw   ,  s   z0_ModuleFrame.finalize_outputs.<locals>.<genexpr>rt   r   valc                 S   s   g | ]}|j d qS )r  )r   r   )rj   or%   r%   r&   rl   P  s     z1_ModuleFrame.finalize_outputs.<locals>.<listcomp>)#r   r   rh   r   outputsr3   r   r   rK   r   rr   RuntimeErrorr   rz   rL   r   r   r   r   r   usersrJ   rH   r/   rM   r   r5   r>   r   r   r   ZProxyrY   r   r   )rB   Zorig_outputsr   r   Ztree_out_nodeZ
parent_outZgraph_outputsZ	orig_nodeZ	user_noder   Zorig_outputZ	proxy_outr%   r  r&   finalize_outputs  s`    
  


z_ModuleFrame.finalize_outputsc                 C   s6   |  d|  | j|| j| j|< || j|j< d S )Ncopying)r   format_noder>   Z	node_copyr   r   r   rr   rX   r%   r%   r&   	copy_node_  s    z_ModuleFrame.copy_nodec                 C   s   d}| j jD ]&}| ||jd|  |d7 }qd}| j| }|jdkrj| | |d7 }| j| }qB| | | j jD ]}|jdkr|| | q|d S )Nr   nn_module_stackrt   rT   r   )	r   rV   r   r   r   r  rW   r  run_from)rB   r   rY   node_idxr%   r%   r&   	run_outerd  s    





z_ModuleFrame.run_outerc                 O   s   | j rt|| d S r?   )r   r   )rB   rP   rQ   r%   r%   r&   r   y  s    z_ModuleFrame.printc              
   C   s  d}|t | jk r| j| }|jdks,t|   | d||  | | j |jdkrzt | jdkrn|S |   |S t |j	di dkrt
d| |jd }ddlm} t |dkr||kr| j}nd	d
 |jd  D }|d t | j | jkr(|   | d| j | | j |S |d k	s6tt| j|r|t | j }| d| t| j| j| j| j| | j|g t|jd  t | j | j|}|d7 }q|| jkst| | |d7 }qd S )Nr   rT   ZSTEPr   rt   r  z(Unable to find nn_module_stack for node )_EMPTY_NN_MODULE_STACK_KEYc                 S   s   g | ]\}}|qS r%   r%   )rj   pathtyr%   r%   r&   rl     s    z)_ModuleFrame.run_from.<locals>.<listcomp>Z	outliningzCreating new stack frame for)rJ   rV   rW   r5   r   r  r   r
  r   r   r  Z(torch._export.passes._node_metadata_hookr  r   rh   r>   r   r   r   r   r   rH   r   r   r  r  )rB   r  Z
module_idxrY   r  r  Znode_module_stackZnext_moduler%   r%   r&   r  }  sd    




	

z_ModuleFrame.run_from)N)r   r    r!   r   r   r   r	   r/   r0   r1   rA   r  r   r
  r  r  r   r  r%   r%   r%   r&   r     s    	

Br   )
orig_graphroot_modulec                 C   s>   i }i }t | t| j||d dgddd |jD |d	  d S )Nrm   c                 S   s   i | ]}|j r|j|j qS r%   )r   rh   ri   r%   r%   r&   r     s    z'_outline_submodules.<locals>.<dictcomp>)rz   )r   rL   rV   r   r  )r  r  r   r   r%   r%   r&   r     s    r   rm   )r   r   r8   c                 C   s   |dkrBt | dd  D ]$}t| |d krt| |tj  qg }t | j D ]J\}}|d krfqT|| }t	|||d d t
| | ||| ||f qT|jtdd |D ]\}}}| || qd S )Nrm   rt   r,   )r8   r   )r   )rH   r   r   r   r/   r0   r1   _modulesr   r   delattrrK   sortr   
itemgetterZregister_module)r   r   r8   rh   childrenrr   childr   r%   r%   r&   r     s    
r   )rz   r}   rv   c              
      s  t t | j D ]D\}tttjj|||g }| D ]\}} | 	| q>qt
| dsf S | j}ttdd |j}|d }	tdd |j}
|
D ]F}t| |jddk	rt krtt fdd|j|_qi }|D ]d}|j|krqd}||j D ]0}|d}|dt| |kr
|} q<q
|dkrHq|||< qg }| D ]\}}t|jd	kr|t|d }t| |}t|tjtjfst||	 |d
d|}W 5 Q R X |j|dd || | |j q^t| t!r| "  t| |iS )aT  Sink params, buffers, and constants from graph inputs into get_attr nodes.

    Exported modules are purely functional, so they pass their parameters and
    buffers in as inputs to the graph.

    To replicate eager's semantics, we need to get them from the module state
    via get_attr instead.

    module: GraphModule, potentially containining nested submodules.
    inputs_to_state: mapping graph input names to the corresponding key in the state_dict.
    scope: tracks where we are in the module hierarchy, so that we can emit the
        right `getattr(self, "foo.bar")` calls, etc.
    r>   c                 S   s
   | j dkS )NrT   r   r   r%   r%   r&   r     r   z_sink_params.<locals>.<lambda>r   c                 S   s
   | j dkS )Nr   r   r  r%   r%   r&   r      r   r,   Nc                    s   | j  t kS r?   )rr   r   r  Zmodule_id_to_inputs_removed	submoduler%   r&   r   (  r   r   r   T)Zpropagate_meta)#r   rH   r  r   r   r   r/   r0   r1   extendrx   r>   filterrV   _recursive_getattrr)   r-   r   rL   rP   rr   rJ   r	  r3   r6   r7   r5   r   r   r   r   Z
erase_noderK   r   rZ   )rz   r}   rv   rr   Zsubmod_id_to_inputs_removedr   r   r>   r   Zthe_last_inputZcall_module_nodesrY   Zinputs_to_state_of_scopeZ
state_nameZsnZsn_splitZinputs_removed	attr_pathZ
state_attrr   r%   r  r&   r     sf      







r   c                 C   s(   |D ]}t | |s d S t| |} q| S r?   )rx   r.   )objr#  attrr%   r%   r&   r"  `  s
    
r"  )T)N)rm   )Grc   r   r   collectionsr   r   enumr   typingr   r   r   r   r	   r
   r   r   r/   Ztorch.fx._pytreerM   Z_pytreer   Ztorch.utils._pytreeutilsre   Z"torch._library.fake_class_registryr   Ztorch.export._tree_utilsr   Ztorch.export.exported_programr   r   r   r   r   r   Ztorch.fx._symbolic_tracer   r   r   __all__r   r6   r7   r0   r1   r   boolr<   r   ABCr   r   r   r\   r   r   r   r   r   r   r   r   r   r   r   r   intr   r   r"  r%   r%   r%   r&   <module>   sv   (  $=  ?  8	  I  
 i