
    ɯwg0                        d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	 d dl
Z
d dlmc mZ d dlmZ d dlmZmZmZ d dlmZmZ ddlmZ dd	lmZmZmZmZ e
j>                  j@                  d
        Z!de
jD                  jF                  deee$      de	ee$e
jD                  jJ                  f   ee$e
jD                  jJ                  f   f   fdZ&de
jD                  jF                  deee$      dee$e
jD                  jJ                  f   dee$e
jD                  jJ                  f   ddf
dZ'	 d&dejP                  deejP                     deee$      defdZ)	 d&de
jD                  jF                  deee$      deee$      dejP                  deejP                     dee$ef   dee$ef   deee$      fdZ*de
jD                  jF                  dedee$ef   dee$ef   ddf
dZ+ G d de,      Z- G d d e
jD                  jF                  e-!      Z.	 d&d"e
jD                  jF                  dee   fd#Z/d$ede
j`                  jb                  fd%Z2y)'    N)chain)AnyDictListOptionalTuple)"_check_input_constraints_for_graph)_assign_attr	_AttrKind_recursive_getattr)_PyTreeCodeGen_PyTreeInfo   )_remove_effect_tokens)ExportedProgramExportGraphSignature	InputKind
OutputKindc                 "   t        j                  |      \  }}|| j                  k7  rt        d| j                   d|       t	        | j
                  j                  D cg c]  }|j                  dk(  s| c}|| j                        S c c}w )Nz>Trying to flatten user inputs with exported input tree spec: 
z-
but actually got inputs with tree spec of: 
placeholder)	pytreetree_flatten_with_path_in_spec
ValueErrorr	   graphnodesoprange_constraints)selfargskwargsflat_args_with_pathreceived_specnodes         Y/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/torch/export/_unlift.py!_check_input_constraints_pre_hookr&      s    )/)F)Ft)L&%M}}o <o
 	
 .****G$dgg.FG Gs    B5Bgmlifted_inputsreturnc                    i }i }| j                   j                  D cg c]  }|j                  dk(  s| }}t        |      t        |      k(  sJ t	        ||      D ]  \  }}||||j
                  <   | j                   j                  |      5  | j                   j                  |      }|j                  |       |j                  }	| j                   j                  |       |	|_	        |||<   ddd        ||fS c c}w # 1 sw Y   xY w)z_
    Unlift inputs referring to params/buffers/constants as getattr nodes in the
    graph
    r   N)r   r   r   lenzipnameinserting_afterget_attrreplace_all_uses_withmeta
erase_node)
r'   r(   unlifted_name_to_nodeinput_name_to_noder$   placeholder_nodes
input_nodelifted_nodegetattr_nodemetadatas
             r%   _unlift_inputs_as_getattrr:   )   s    *,((..U$DGG}<TUU}%6!7777#&'8-#H B
K2<z/ ))*5 B!xx00=00>%??##J/$,!5A%k2B BB !"444 VB Bs   C>C>A DD	mutated_outputsr3   r4   c                    d}| j                   j                  D ]  }|j                  dk(  s|} n |J t        j                  |j
                        d   }t        |      t        |      k(  sJ g }i }t        ||      D ]  \  }	}
|
|j                  |	       |
|v r||
   }n|
|v r||
   }nt        d|
 d      | j                   j                  |      5  | j                   j                  t        j                  j                  j                  j                   ||	f      }|||	<   ddd        |D cg c]  }||v r||   n| }}| j                   j                  |      5  | j                   j#                  t%        |            }|j&                  j)                  |j&                         |j+                  |       | j                   j-                  |       ddd       y# 1 sw Y   nxY wc c}w # 1 sw Y   yxY w)zt
    Find the all the buffers and inputs that were mutated and insert copy_
    operators to reflect mutations.
    Noutputr   zCould not find z  in either buffer or input nodes)r   r   r   r   tree_flattenr    r+   r,   appendRuntimeErrorinserting_beforecall_functiontorchopsatencopy_defaultr=   tupler1   updater0   r2   )r'   r;   r3   r4   output_noder$   outputsuser_output_nodesreturn_nodes_to_copyreturn_nodemutated_node_namemutated_node	copy_nodeoutput_args
new_outputs                  r%   _insert_copy_for_mutationsrT   F   s    K 77hK """!!+"2"23A6Gw<3////*-g*G :&&$$$[1 5501BCL"44-.?@L!"3!44TU  XX&&{3 	:..		$$,,|[.II 1: -		: 	::, & '+.B&BT"LK  
	"	";	/ )XX__U;%78
{//0))*5
K() )	: 	:) )s    AG$6G1%A6G6$G.	6G?in_specout_specforward_arg_namesc                    |r|}n| j                   t        k(  r| j                  dk(  r| j                  d   j                   t        k(  r{| j                  d   j                   t        k(  r[t        | j                  d   j                        D cg c]  }d| 	 }}|j                  | j                  d   j                         n%t        | j                        D cg c]  }d| 	 }}t        t        || |            S c c}w c c}w )zK
    Create the codegen for the graph module based on the in/out specs
       r   r   arg_)
typerH   num_childrenchildren_specsdictrangeextendcontextr   r   )rU   rV   rW   namesis        r%   _get_codegenrd   {   s     ! LLE!$$)&&q)..%7&&q)..$6 */w/E/Ea/H/U/U)VWAtA3ZWEWLL//2::;).w/C/C)DEAtA3ZEEE	
  X Fs   C>D
state_dict	constantsc                     t        | |      \  }}	t        | |||	       t        |||      | j                  _        | j                  j                          | j                          | S )a  
    Args:
        lifted_inputs: A list matching the graph module's input nodes. For
        an input node that is referring to a lifted parameter/buffer, this
        list will contain the fqn the corresponding attribute. Otherwise, this
        list will contain None. This is used to unlift the lifted parameters as
        get_attr nodes.

        mutated_outputs: A list matching the graph module's output nodes. For
        an output node that is referring to a mutated buffer or user input, this
        list will contain the name of the corresponding buffer or user input
        that needs to be mutated. Otherwise, this list will contain None. This
        is used to re-insert an inplace copy_ operator to copy the mutated
        values back to the original node.
    )r:   rT   rd   r   _codegenlint	recompile)
r'   r(   r;   rU   rV   re   rf   rW   r3   r4   s
             r%   _unliftrk      sc    2 1J
M1-- 
O24F %Wh8IJBHHHHMMOLLNI    new_gmgraph_signaturec                    t        |j                        }|j                  D ]3  }||v rd}||   }nd}||   }t        || |t        j
                  |       5 |j                  D ]$  }||   }t        || |t        j                         & t        |j                  |j                        D ]$  }||   }t        || |t        j                         & y )NFT	attr_kind
persistentrq   )setnon_persistent_buffersbuffersr
   r   BUFFER
parameters	PARAMETERr   lifted_custom_objslifted_tensor_constantsCONSTANT)rm   rn   re   rf   ru   r-   rr   values           r%   _register_attrs_to_new_gmr~      s     !!G!GH'' 	
))JdOEJt$E649+;+;
	
	
  ** 
4 ))		

 **O,S,S 	
 $((		
		
rl   c                   *     e Zd ZdZd Zd fd	Z xZS )_StatefulGraphModuleFactoryzO
    Metaclass that ensures a private constructor for _StatefulGraphModule
    c                 L    t        | j                   d| j                   d      )N.z has no public constructor. )	TypeError
__module____qualname__)clsr    r!   s      r%   __call__z$_StatefulGraphModuleFactory.__call__   s,    ~~a 0 011MN
 	
rl   c                 (    t         |   |||      S )Nr   )superr   )r   rootr   r   	__class__s       r%   _createz#_StatefulGraphModuleFactory._create   s#    w/   
 	
rl   N)__name__r   r   __doc__r   r   __classcell__r   s   @r%   r   r      s    


 
rl   r   c                         e Zd Zd fd	Z xZS )_StatefulGraphModulec                 <    t         |   ||       |xs g | _        y r   )r   __init__r   )r   r   r   r   r   s       r%   r   z_StatefulGraphModule.__init__   s    u%!2!8brl   r   )r   r   r   r   r   r   s   @r%   r   r      s    9 9rl   r   )	metaclassplain_graph_modulec                 <   t         j                  | | j                  |      }|j                  t        d       ||S |j
                  D ]  }|j                  |      }|j                  r)t        j                  d| d       |j                         }|j                  d      ^ }}t        ||      }t        ||       t        |||t        j                           |j"                  D ]/  }t        | j                  |      ||t        j$                  d	       1 |S )
Nr   T)with_kwargszA model attribute `z` requires gradient. but it's not properly registered as a parameter. torch.export will detach it and treat it as a constant tensor but please register it as parameter instead.r   rs   Frp   )r   r   r   register_forward_pre_hookr&   r{   
get_bufferrequires_gradwarningswarndetachrsplitr   delattrr
   r   r|   ru   rw   )	r   r   rn   stateful_gmconstant_fqnbufferprefixfieldsubmods	            r%   _create_stateful_graph_moduler      s4    '..  + / K )))t *   (?? V ''5MM%l^ 4? @ ]]_F%,,S1#K8V[,)BTBTU%V. "88 
))&1&&	

 rl   epc           
      F   t        |       } t        j                  j                  | j                  t        j                  | j                              }t        || j                  | j                  | j                         | j                  j                  j                  d      }| j                  j                  D cg c]Z  }|j                  t         j"                  t         j$                  t         j&                  t         j(                  fv r|j*                  nd \ }}| j                  j,                  D cg c]<  }|j                  t.        j0                  t.        j2                  fv r|j*                  nd > }}t5        |||| j6                  j8                  | j6                  j:                  | j                  | j                  |      }t=        || j>                  | j                        }|j                  jA                  | j                  j                         |S c c}w c c}w )NrW   )rW   )!r   rC   fxGraphModulegraph_modulecopydeepcopyr   r~   rn   re   rf   r1   getinput_specskindr   rw   CONSTANT_TENSORry   
CUSTOM_OBJtargetoutput_specsr   BUFFER_MUTATIONUSER_INPUT_MUTATIONrk   	call_specrU   rV   r   r   rI   )r   rm   rW   rU   r(   rV   r;   	unlift_gms           r%   &_unlift_exported_program_lifted_statesr   <  s   	r	"BXX!!"//4==3JKFfb&8&8"--V,,001DE ))55*  ||  ))##$$	 NN *M *, **77, 	 }}**J,J,JKL OO ,O , 



+	F .$$b&8&8I NN"//../O*,s   <AH5AHr   )3r   r   	itertoolsr   typingr   r   r   r   r   rC   torch.utils._pytreeutils_pytreer   torch._export.utilsr	   torch.export.unflattenr
   r   r   torch.fx.graphr   r   _remove_effect_tokens_passr   exported_programr   r   r   r   _dynamodisabler&   r   r   strNoder:   rT   TreeSpecrd   rk   r~   r[   r   r   r   nnModuler    rl   r%   <module>r      s      3 3  $ $ B N N 6 =   $55&5 4UXX]]"#T#uxx}}*<%==>5:2)2)(3-(2)  UXX]] 232) S%((--/0	2)
 
2)p .2__v'  S	* 	R .2""&" (3-(" __	"
 v'" S#X" CH~"  S	*"J#
HH  #
)#
 S#X#
 CH~	#

 
#
L
$ 
$9588//;V 9 7;9,,9
 239x- -588?? -rl   