
    ig4                        S SK Jr  S SKrS SKJr  S SKJrJrJrJ	r	J
r
Jr  S SKJr  S SKJrJrJrJrJrJr  S\R*                  R,                  S\R.                  S	\R.                  4S
 jrS\R*                  R2                  S	\4S jrS\S\R*                  R2                  S	\4S jrS\S\R*                  R2                  S	\\R.                     4S jr SS\S\R*                  R,                  S\S\S\R.                  S\\   S	\R*                  R2                  4S jjrS\S\R*                  R2                  4S jr S\4S jr!S\S\\-  S	\R*                  R2                  4S jr"S\S\S\R.                  S	\R*                  R2                  4S jr#g)    )OptionalN)ExportedProgram)
get_bufferget_lifted_tensor_constant	get_param	is_bufferis_lifted_tensor_constantis_param)FakeTensorConverter)ExportGraphSignature	InputKind	InputSpec
OutputKind
OutputSpecTensorArgumentgraphdatareturnc                 n   [        U R                  5      nU(       d  [        S5      eUS   n[        UR                  S   [
        [        R                  R                  R                  45      (       a  UR                  S   S   nOUR                  S   n[        5       R                  UR                  US9$ )aO  
Helper function to create a fake tensor using the fake_mode from existing nodes in the graph.

Args:
    graph: The graph to get fake_mode from
    data: The tensor data to create fake tensor for

Returns:
    A fake tensor with the appropriate fake_mode

Raises:
    RuntimeError: If the graph has no nodes to extract fake_mode from
zGCannot create fake tensor: graph has no nodes to extract fake_mode fromr   val)t)listnodesRuntimeError
isinstancemetatupletorchfximmutable_collectionsimmutable_listr   from_real_tensor	fake_mode)r   r   r   example_nodeexample_fake_tensors        c/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/executorch/backends/transforms/utils.py_get_fake_tensor_moder'      s     EU
 	
 8L% 5%((*H*H*W*W"X  +//6q9*//6 112E2O2OSW1XX    nodec                 v    [        U [        R                  R                  5      =(       a    U R                  S:H  $ )zM
Returns true if the given node is a get attr node for a tensor of the model
get_attr)r   r   r   Nodeop)r)   s    r&   is_get_attr_noder.   >   s'     dEHHMM*Dtww*/DDr(   exp_progc                     [        U5      =(       d/    [        X5      =(       d    [        X5      =(       d    [        X5      $ N)r.   r
   r   r	   r/   r)   s     r&   is_param_noder3   E   s8     	5H#	5X$	5 %X4	r(   c                    Uc  g [        X5      (       a  [        X5      $ [        X5      (       a  [        X5      $ [	        X5      (       a  [        X5      $ [        U5      (       a+   [        UR                  R                  UR                  5      $ [        SUR                   S35      e! [         a#    [        U R                  UR                  5      s $ f = f)Nzunsupported param type, .)r
   r   r   r   r	   r   r.   getattrr   owning_moduletargetAttributeErrorgraph_moduler   r-   r2   s     r&   get_param_tensorr;   N   s     |	(	!	!((	8	"	"())	"8	2	2)(99	$			?4::33T[[AA 1$''!<
==  	?800$++>>	?s   ')B* **CCexp_programnamekindpersistent_bufferc                   ^ UnU=[         R                  :X  a-    [        R                  R	                  USS9U R
                  U'   Ov=[         R                  :X  a4    Uc  [        S5      eU(       a  X@R
                  U'   O=X@R                  U'   O.[         R                  :X  a  X@R                  U'   O [        S5      e[        X5      nUR                  SX"S9nXxR                  S'   UR                   V	s/ s H   oR                  S:X  d  M  U	R                  PM"     n
n	U
R!                  U5      mU R"                  R$                  n['        U5       VVs/ s H'  u  pUR(                  [         R*                  :X  d  M%  UPM)     nnn[-        U4S jU 5       5      (       d  [        S	U S
35      e[/        U5      n[1        X?Xe5      nUR3                  TU5        [5        XR"                  R6                  5      nUU l        U$ s  sn	f s  snnf )a  
Creates and returns a constant placeholder node, meaning that it is of type parameter, buffer,
or lifted constant tensor. graph.inserting_before/after() should be used before the call to
decide where to insert the node, at an insertion point before the first input node.
F)requires_gradz6Must set persistent_buffer when creating a new buffer.z%Can only create constant input nodes.placeholderr-   r=   r8   r   c              3   ,   >#    U  H	  oT:  v   M     g 7fr1    ).0user_input_index
node_indexs     r&   	<genexpr>.create_constant_placeholder.<locals>.<genexpr>   s     S@R,<Z	'@Rs   zFailed to insert zP; Const placeholder nodes must be inserted before user input nodes in the graph.)r   	PARAMETERr   nn	Parameter
state_dictBUFFERr   	constantsCONSTANT_TENSORr'   create_noder   r   r-   r=   indexgraph_signatureinput_specs	enumerater>   
USER_INPUTallr   r   insertr   output_specs_graph_signature)r<   r   r=   r>   r   r?   r8   fake_tensorr)   n
node_namesrU   ispecuser_input_indicesarg_spec
input_specnew_graph_signaturerH   s                     @r&   create_constant_placeholderre   b   s    F  Y  -2XX-?-?E .@ .K""6* Y ("L  #15&&v.04%%f-&&,0!!&)FGG'4K DFD"IIe #(++G+Q1F&!&&+JG!!$'J--99K";//ga499	@T@T3T/   S@RS  v%uv
 	
 d#H46EJz:..00== $7K K/ Hs   3G<
G<$H9Hc                    [        UR                  5      S:X  d  [        SUR                   S35      eUR                  U R                  R
                  ;   a1  U R                  R
                  UR                     nU R                  U	 OUR                  U R                  R                  ;   aX  U R                  R                  UR                     nX R                  R                  ;   a  U R                  U	 O|U R                  U	 OnUR                  U R                  R                  ;   a1  U R                  R                  UR                     nU R                  U	 O[        SUR                   S35      eU R                  R                   Vs/ s H+  nUR                  R                  UR                  :w  d  M)  UPM-     nn[        X@R                  R                  5      nXPl        UR                   R#                  U5        gs  snf )z
Deletes a node of type parameter, buffer, or lifted constant tensor and its related
graph signature and state_dict/constant entries. The node may not have any users.
r   zCannot delete input node z! since it has users in the graph.zE since it is not a parameter, a buffer, nor a lifted tensor constant.N)lenusersr   r=   rT   inputs_to_parametersrN   inputs_to_buffersnon_persistent_buffersrP   !inputs_to_lifted_tensor_constantsrU   argr   rZ   r[   r   
erase_node)r<   r)   r8   r`   rU   rd   s         r&   delete_constant_placeholderro      s   
 tzz?a'		{2ST
 	

 yyK//DDD,,AA$))L""6*	k11CC	C,,>>tyyI00GGG%%f-&&v.	k11SS	S,,NNII
 !!&)'		{2wx
 	
  //;;;D88==DII% 	;  
 /00== $7  	JJ$s   
(G?6G?c                 F   U R                   R                   Vs/ s H  oR                  S:X  d  M  UPM     nn[        U5      [        U R                  R
                  5      :w  a8  [        S[        U5       S[        U R                  R
                  5       S35      e[        X R                  R
                  5       HX  u  p4UR                  UR                  R                  :w  d  M+  [        SUR                   SUR                  R                   35      e   U R                   R                  5       R                  S   n[        U5      [        U R                  R                  5      :w  a8  [        S[        U5       S[        U R                  R                  5       S	35      e[        XPR                  R                  5       HX  u  p6UR                  UR                  R                  :w  d  M+  [        S
UR                   SUR                  R                   35      e   gs  snf )zB
Validates that the graph signature is up to date with the graph.
rB   z
Graph has z% placeholder nodes but signature has z input specszInput node z does not match input spec r   z  output nodes but signature has z output specszOutput node z does not match output spec N)r   r   r-   rg   rT   rU   r   zipr=   rm   output_nodeargsrZ   )r<   r]   placeholdersr)   rc   outputsoutput_specs          r&   _validate_graph_signaturerw      s     +0066P6!$$-:OA6LP
<C ; ; G GHH\*++P;..::;<LJ
 	
  .I.I.U.UV99
+++dii[(CJNNDWDWCXY  W
 ++-2215G
7|s;66CCDDW&F;..;;<=]L
 	
 !*E*E*R*RS99,,,tyyk)EkooFZFZE[\  T# Qs
   HHr`   c                 $   [        US5      (       a2  [        UR                  S5      (       a  UR                  R                  nO[        SU 35      eU R                  R
                   H  nUR                  U:X  d  M  Us  $    [        SU S35      e)zM
Converts an InputSpec or OutputSpec to its corresponding node in the graph.
rm   r=   zInvalid spec format: zCould not find node with name 'z' in the graph)hasattrrm   r=   r   r   r   )r<   r`   arg_namer)   s       r&   _spec_to_noder{      s     tU& 9 988==24&9:: !!''99 K ( 8
.Q
RRr(   c                    U(       a  UR                  5       (       d  [        S5      e[        U[        R                  5      (       d  [        S5      eUR                  S5      (       a  USS nOUnX0R                  ;   a  [        SU S35      e[        U 5        SnX R                  U'   U R                  R                  n[        XR5      nS	nSnU R                  R                  n	[        U	5      S	:X  d  [        S
 U	 5       5      (       a  [        U	5      nUR!                  SXS9nOy[#        U	5       Hj  u  pUR$                  [&        R(                  [&        R*                  4;   d  M5  U
nUR-                  [/        X5      5         UR!                  SXS9nSSS5          O   Uc   S5       eXhR0                  S'   [3        [&        R4                  [7        U5      X45      nU	R9                  X|5        [#        U R                  R:                  5       V
Vs/ s H'  u  pUR$                  [<        R>                  :X  d  M%  U
PM)     nn
nU(       a  US	   OS	nU R                  R:                  n[A        [<        RB                  [7        U5      U5      nUR9                  UU5        URE                  5       n[G        URH                  S	   5      nUR9                  X5        U4Ul$        [K        X5      nUU l&        U$ ! , (       d  f       GNb= fs  snn
f )a  
Creates and returns a mutable buffer placeholder node. This is similar to
create_constant_placeholder but specifically for creating mutable buffers that
can be modified during execution.

The difference between this and create_constant_placeholder is that this doesn't
expect user to set the correct position for the placeholder node to be inserted,
it finds the correct position automatically.

It also updates the graph outputs to include the mutable buffer.

Args:
    exp_program: The exported program to modify
    name: The name for the new buffer node (should start with "b_" prefix by convention)
    data: The initial tensor data for the buffer

Returns:
    The created placeholder node to be used in the graph
zBuffer name cannot be emptyzData must be a torch.Tensorb_   NzBuffer target 'z' already exists in state_dictTr   c              3   |   #    U  H2  nUR                   [        R                  [        R                  4;  v   M4     g 7fr1   )r>   r   rQ   rW   )rF   r`   s     r&   rI   (create_mutable_buffer.<locals>.<genexpr>H  s1      $D 			)33Y5I5IJJs   :<rB   rC   z$node should be created at this pointr   )'strip
ValueErrorr   r   Tensor
startswithrN   r   rw   r:   r   r'   rT   rU   rg   rX   rR   rV   r>   r   rQ   rW   inserting_beforer{   r   r   rO   r   rY   rZ   r   USER_OUTPUTr   BUFFER_MUTATIONrr   r   rs   r   r[   )r<   r=   r   r8   r?   r   r\   rH   r)   rU   r_   r`   buffer_input_specuser_output_indicesoutput_indexrZ   mutation_output_specrr   rs   rd   s                       r&   create_mutable_bufferr     s   2 tzz||677dELL))677 tab '''_VH4RSTTk*%)6"$$**E (4K JD--99K
;1 $$ ! !
 %
  M J !-GAyyY66	8L8LMM
++M+,LM ,,D,VD N . CCC"IIe!.. z5 !!<!<!I!IJJGA99
... 	
J   .A&q)aL..;;L%""N4$8& &:; ##%K  #$DKK#wK /{I#6K KK NMs   K.$L 6L .
K=	r1   )$typingr   r   executorch.exirr   torch._export.utilsr   r   r   r   r	   r
   torch._subclasses.fake_tensorr   torch.export.graph_signaturer   r   r   r   r   r   r   Graphr   r'   r,   boolr.   r3   r;   strre   ro   rw   r{   r   rE   r(   r&   <module>r      s     +  > Y Yu|| Y Y>E588== ET EO 588== T >>%*XX]]>ell>4 )-B B88>>B B 	B
 ,,B  ~B XX]]BJ- _ - EHHMM - `? 8S S(1J(>S
XX]]S(r r
r ,,r XX]]	rr(   