o
    Zh<                     @   s  d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	Z	d dl
m  mZ d dlmZmZmZ d dlmZ d dlmZmZ d dlmZmZ d	d
lmZ d	dlmZ d	dlmZm Z m!Z!m"Z" dej#de$fddZ%e	j&j'dd Z(de	j)j*deee+  de,e-e+e	j)j.f e-e+e	j)j.f f fddZ/de	j)j*deee+  de-e+e	j)j.f de-e+e	j)j.f ddf
ddZ0	d3dej#deej# dee$e+  defddZ1	d3de	j)j*deee+  deee+  dej#deej# d e-e+ef d!e-e+ef dee$e+  fd"d#Z2d$e	j)j*d%e d e-e+ef d!e-e+ef ddf
d&d'Z3G d(d) d)e4Z5G d*d+ d+e	j)j*e5d,Z6d-e	j)j*d.ede6fd/d0Z7d.ede	j8j9fd1d2Z:dS )4    N)Sequence)chain)AnyOptional),_enter_enable_graph_inputs_of_type_nn_module+_exit_enable_graph_inputs_of_type_nn_module#_get_graph_inputs_of_type_nn_module)"_check_input_constraints_for_graph)_assign_attr	_AttrKind)_PyTreeCodeGen_PyTreeInfo   )_remove_effect_tokens)reorder_kwargs)ExportedProgramExportGraphSignature	InputKind
OutputKindin_specreturnc                 C   s>   t ||}t| |f\}}||krtd| d| d|S )Nz>Trying to flatten user inputs with exported input tree spec: 
z-
but actually got inputs with tree spec of: 
zi.
Please check that the inputs have the same number of args and kwargs as the ones you used when tracing.)r   pytreeZtree_flatten_with_path
ValueError)argskwargsr   Zreordered_kwargsflat_args_with_pathZreceived_spec r   C/var/www/auris/lib/python3.10/site-packages/torch/export/_unlift.py_check_inputs_match   s   
	r   c                 C   s8   | j sd S t||| j}tdd | jjD || j d S )Nc                 S      g | ]	}|j d kr|qS placeholderop.0noder   r   r   
<listcomp>8       z5_check_input_constraints_pre_hook.<locals>.<listcomp>)validate_inputsr   Z_in_specr	   graphnodesrange_constraints)selfr   r   r   r   r   r   !_check_input_constraints_pre_hook0   s   r.   gmlifted_inputsc           	   	   C   s   i }i }dd | j jD }t|t|ksJ t||D ]?\}}|du r*|||j< q| j |# | j |}|| |j}| j 	| ||_|||< W d   n1 sVw   Y  q||fS )z_
    Unlift inputs referring to params/buffers/constants as getattr nodes in the
    graph
    c                 S   r   r    r"   r$   r   r   r   r'   I   r(   z-_unlift_inputs_as_getattr.<locals>.<listcomp>N)
r*   r+   lenzipnameZinserting_afterZget_attrreplace_all_uses_withmeta
erase_node)	r/   r0   unlifted_name_to_nodeinput_name_to_nodeZplaceholder_nodesZ
input_nodeZlifted_nodeZgetattr_nodemetadatar   r   r   _unlift_inputs_as_getattr>   s"   

r:   mutated_outputsr7   r8   c              	      s  d}| j jD ]}|jdkr|} nq|dusJ t|jd }t|t|ks*J g }i  t||D ]O\}}	|	du rA|| q3|	|v rJ||	 }
n|	|v rS||	 }
nt	d|	 d| j 
| | j tjjjj|
|f}| |< W d   n1 s}w   Y  q3 fdd|D }| j 
|' | j t|}|| | j | |j|_|j|j W d   dS 1 sw   Y  dS )zt
    Find the all the buffers and inputs that were mutated and insert copy_
    operators to reflect mutations.
    Noutputr   zCould not find z  in either buffer or input nodesc                    s    g | ]}| v r | n|qS r   r   r$   Zreturn_nodes_to_copyr   r   r'      s    z._insert_copy_for_mutations.<locals>.<listcomp>)r*   r+   r#   r   Ztree_flattenr   r1   r2   appendRuntimeErrorZinserting_beforeZcall_functiontorchopsZatenZcopy_defaultr<   tupler4   r6   r3   r5   update)r/   r;   r7   r8   Zoutput_noder&   ZoutputsZuser_output_nodesZreturn_nodeZmutated_node_nameZmutated_nodeZ	copy_nodeZoutput_argsZ
new_outputr   r=   r   _insert_copy_for_mutations[   sN   








"rE   out_specforward_arg_namesc                 C   s   |r|}n;| j tkr6| jdkr6| jd j tkr6| jd j tkr6dd t| jd jD }|| jd j n
dd t| jD }tt	|| |S )zK
    Create the codegen for the graph module based on the in/out specs
       r   r   c                 S      g | ]}d | qS Zarg_r   r%   ir   r   r   r'          z _get_codegen.<locals>.<listcomp>c                 S   rI   rJ   r   rK   r   r   r   r'      rM   )
typerC   Znum_childrenZchildren_specsdictrangeextendcontextr   r   )r   rF   rG   namesr   r   r   _get_codegen   s    

rT   
state_dict	constantsc           
      C   sB   t | |\}}	t| |||	 t|||| j_| j  |   | S )a  
    Args:
        lifted_inputs: A list matching the graph module's input nodes. For
        an input node that is referring to a lifted parameter/buffer, this
        list will contain the fqn the corresponding attribute. Otherwise, this
        list will contain None. This is used to unlift the lifted parameters as
        get_attr nodes.

        mutated_outputs: A list matching the graph module's output nodes. For
        an output node that is referring to a mutated buffer or user input, this
        list will contain the name of the corresponding buffer or user input
        that needs to be mutated. Otherwise, this list will contain None. This
        is used to re-insert an inplace copy_ operator to copy the mutated
        values back to the original node.
    )r:   rE   rT   r*   Z_codegenZlintZ	recompile)
r/   r0   r;   r   rF   rU   rV   rG   r7   r8   r   r   r   _unlift   s   
rW   new_gmgraph_signaturec                 C   s   t |j}|jD ]}||v rd}|| }nd}|| }t|| |tj|d q|jD ]}|| }t|| |tjd q)t|j	|j
D ]}|| }t|| |tjd q@d S )NFT	attr_kind
persistentr[   )setnon_persistent_buffersbuffersr
   r   BUFFER
parameters	PARAMETERr   Zlifted_custom_objslifted_tensor_constantsCONSTANT)rX   rY   rU   rV   r_   r3   r\   valuer   r   r   _register_attrs_to_new_gm   s:   




rg   c                       s*   e Zd ZdZdd Zd fdd	Z  ZS )_StatefulGraphModuleFactoryzO
    Metaclass that ensures a private constructor for _StatefulGraphModule
    c                 O   s   t | j d| j d)N.z has no public constructor. )	TypeError
__module____qualname__)clsr   r   r   r   r   __call__  s   z$_StatefulGraphModuleFactory.__call__Nc                    s   t  j|||dS )Nr,   )superrn   )rm   rootr*   r,   	__class__r   r   _create
  s
   z#_StatefulGraphModuleFactory._createN)__name__rk   rl   __doc__rn   rt   __classcell__r   r   rr   r   rh      s    rh   c                       s   e Zd Zd fdd	Z  ZS )_StatefulGraphModuleNc                    s"   t  || |p
g | _d| _d S )NT)rp   __init__r,   r)   )r-   rq   r*   r,   rr   r   r   rz     s   

z_StatefulGraphModule.__init__ru   )rv   rk   rl   rz   rx   r   r   rr   r   ry     s    ry   )	metaclassplain_graph_moduleepc                    s  t j| | j|d}t|j | fdd |jtdd |j fdddd i }|jj	D ];}|
|}|jrLtd| d	 | }|||< |}|d
^ }}	tjj||}
t|
|	 t|||tjd q/|j D ]:\}}tjj||st|tjr|jrtd| d ||v r|| }n
| }|||< |}t|||tjd qp|jjD ]}t| 
|||tjdd q|S )Nro   c                        t  S ru   )r   r   r   Zmodule_typesr   r   <lambda>'      z/_create_stateful_graph_module.<locals>.<lambda>T)Zwith_kwargsc                     r~   ru   )r   r   r   r   r   r   0  r   )Zalways_callzA model attribute `z` requires gradient. but it's not properly registered as a parameter. torch.export will detach it and treat it as a constant tensor but please register it as parameter instead.ri   r]   z` requires gradient but it's not properly registered as a parameter. torch.export will detach it and treat it as a constant tensor but please register it as parameter instead.FrZ   )ry   rt   r*   r   Zexample_inputsZregister_forward_pre_hookr.   Zregister_forward_hookrY   rd   
get_bufferZrequires_gradwarningswarndetachrsplitr@   fxgraph_moduleZ_get_attr_via_attr_listdelattrr
   r   re   rV   itemsZ	_has_attr
isinstanceZTensorr_   ra   )r|   r,   r}   Zstateful_gmZ"original_tensor_to_detached_tensorZconstant_fqnbufferZdetached_bufferprefixfieldZsubmodZ
const_namerf   Zdetached_valuer   r   r   _create_stateful_graph_module  st   








r   c              
   C   s   | j d jdkrt| } tj| jt| j	}t
|| j| j| j | jd j }r-|jnd }dd | jjD }dd | jjD }t|||| jj| jj| j| j|d}t|| j| }|j| jj |S )Nr   ZTRAININGc                 S   s0   g | ]}|j tjtjtjtjfv r|jnd qS ru   )kindr   ra   ZCONSTANT_TENSORrc   Z
CUSTOM_OBJtarget)r%   r   r   r   r   r'     s    z:_unlift_exported_program_lifted_states.<locals>.<listcomp>c                 S   s(   g | ]}|j tjtjfv r|jnd qS ru   )r   r   ZBUFFER_MUTATIONZUSER_INPUT_MUTATIONr   )r%   rF   r   r   r   r'     s    
)rG   )Z	verifiersdialectr   r@   r   GraphModuler   copydeepcopyr*   rg   rY   rU   rV   Zmodule_call_graph	signaturerG   Zinput_specsZoutput_specsrW   Z	call_specr   rF   r   r,   r5   rD   )r}   rX   sigrG   r0   r;   Z	unlift_gmr   r   r   &_unlift_exported_program_lifted_states  s2   

r   ru   );r   r   collections.abcr   	itertoolsr   typingr   r   r@   Ztorch.utils._pytreeutilsZ_pytreer   Ztorch._export.non_strict_utilsr   r   r   Ztorch._export.utilsr	   Ztorch.export.unflattenr
   r   Ztorch.fx.graphr   r   Z_remove_effect_tokens_passr   Z_tree_utilsr   Zexported_programr   r   r   r   ZTreeSpeclistr   Z_dynamodisabler.   r   r   strrC   rO   Noder:   rE   rT   rW   rg   rN   rh   ry   r   nnModuler   r   r   r   r   <module>   s   

"


9

)





%


)
e