
    ɯwge'                       d dl mZ d dlZd dlZd dlZd dlmZmZmZm	Z	 d dl
Z
d dlmc 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 d dlmZ d d	lmZ d
dlmZ e
j>                  j@                  Z e
j>                  jB                  Z! ejD                  e#      Z$	 	 	 	 	 	 	 	 ddZ%	 	 	 	 	 	 	 	 ddZ& G d de
jN                        Z(d Z)ddZ*ddZ+ddZ,ddZ-y)    )annotationsN)AnyListOptionalTuple)dynamo_timedlazy_format_graph_code)MutationType)fx_graph_cse)constant_foldreplace_node_with_constant)freezing_passes)view_to_reshape   )configc                   | j                   j                  d      }|dt        |       }g }|j                  D cg c]  }|j                  |j                   }}t        |j                        D 	cg c]3  \  }}	|	j                  t        j                  t        j                  fv r|5 }
}}	t        t        ||            D ]/  \  }\  }}||
v s||v r|j                  |       #t        | ||       1 |j                  t        t        |      t        |                   | j!                          |S c c}w c c}	}w )z
    Replaces the parameters of a PyTorch GraphModule with constants wherever possible.
    Returns a list of indices representing the input parameters that were not converted to constants.
    placeholderopN)graph
find_nodeslenoutput_infobase_idx	enumerate
input_infomutation_typer
   MUTATED_IN_GRAPHMUTATED_OUT_GRAPHzipappendr   extendrange	recompile)gmflat_paramsfw_metadataparamsfake_inp_nodespreserved_arg_indicesout_infoaliased_input_argsimmutated_inps
real_inputnodes                ]/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/torch/_inductor/freezing.pyreplace_params_with_constantsr3      sE    XX  M 2FMc&k*N $//( 	  k445Aq??))<+I+IJK 	
L  "+3{N+K!L 9J%7 7!((+"2tZ8	9   s;'7V!EFLLN  1s   D548D:c                   t        |       t        j                  j                  j	                         x}r,|j
                  }|j                  }||J t        |||      }n9|j                  j                  d      }t        t        t        |                  }t        |j                        }||_        |j                          |D 	cg c]  }	||	   	 }
}	t        ||
       t!        |       t"        j$                  rt'                t)        |        t*        j-                  dt/        d|d             ||fS c c}	w )a5  
    Inlines parameters that are not mutated into constants and optimizes the graph through constant propagation
    and other techniques. If enabled, the function also discards the original parameters of the module for memory efficiency.

    Assumes that this function is run in dynamo tracing post aot_autograd.

    Args:
        dynamo_gm (torch.fx.GraphModule): The Dynamo constructed GraphModule.
        aot_autograd_gm (torch.fx.GraphModule): The aot_autograd constructed GraphModule to be frozen.
        example_inputs (List[torch.Tensor]): A list of example input tensors to be used in the freezing process.

    Returns:
        Tuple[torch.fx.GraphModule, List[int]]: A tuple containing the frozen GraphModule and a list of indices
        of the inputs that were preserved (not turned into constants).
    r   r   z%szFROZEN GRAPHT)colored)r   torch_guardsTracingContexttry_getr'   params_flatr3   r   r   listr#   r   r   r$   r   r   r   freezing_discard_parametersinvalidate_eager_modulesdiscard_traced_gm_paramslogdebugr	   )	dynamo_gmaot_autograd_gmexample_inputstracing_contextr'   r:   r*   inputs	cse_graphindaot_example_inputss              r2   freezerI   B   s*   . O$--66>>@@@%11%11&;+BBB =[+!
 !&&11]1C $U3v;%7 8 _223I%O9NO#.-OOO%78/")) " +II$^_dS 111 Ps   D;c                  B     e Zd Ze fd       ZddZedd       Z xZS )ErasedTensorc                D    t         |   | |j                  d            S )Nmeta)device)super__new__to)clselemname
owning_mod	__class__s       r2   rP   zErasedTensor.__new__}   s    wsDGG6G$:;;    c                F    || _         t        j                  |      | _        y )N)erased_nameweakrefrefowning_mod_ref)selfrS   rT   mods       r2   __init__zErasedTensor.__init__   s    %kk#.rW   c           	         t        j                  |i |D cg c]  }t        |t              r| }}t	        |      dkD  sJ |d   }t        d| d|j                   d|j                                c c}w )Nr   zTrying to run Pytorch Eager Module after Dynamo Freezing. The original parameters have been discarded for memory efficiency. Found in op z for erased parameter z of )pytreearg_tree_leaves
isinstancerK   r   RuntimeErrorrY   r\   )rR   functypesargskwargseerased_tensorss          r2   __torch_dispatch__zErasedTensor.__torch_dispatch__   s     ++T<V<
!\* 
 

 >"Q&&&1& 6q}}oT!JZJZJ\I]_
 	

s   A4)rT   zOptional[str]returnNone) N)	__name__
__module____qualname__staticmethodrP   r_   classmethodrk   __classcell__)rV   s   @r2   rK   rK   |   s.    < </ 
 
rW   rK   c            
        t         j                  j                  j                         5  t         j                  j
                  j                         j                  j                  j                         D ]  } t        | t         j                  j                        s(t        t        j                  | j!                  d      | j#                  d                  D ]  \  }}t         j$                  j&                  j)                         5  t+        |||       }d d d        t        |t         j                  j,                        rj/                  d       d|_        t3        | |         	 d d d        y # 1 sw Y   `xY w# 1 sw Y   y xY wNF)recurseT)r6   utils_python_dispatch_disable_current_modesr7   r8   getmodule_context
nn_modulesvaluesrc   nnModuler;   	itertoolschainnamed_parametersnamed_buffers	_dispatchpythonno_python_dispatcherrK   	Parameterrequires_grad_	_is_paramsetattrr^   	attr_nametensore_ts       r2   r=   r=      s8   		%	%	<	<	> - ]]))--/>>IIPPR	-c588??3%)(((7%%e%4& -!	6 __++@@B ?&vy#>C?fehh&8&89&&t,$(CMY,-	-- -? ?- -s%   C F	E6	AF6E?;FFc           	     4   t         j                  j                  j                         5  t	        t        j                  | j                  d      | j                  d                  D ]  \  }}t         j                  j                  j                         5  t        |||       }d d d        t        |t         j                  j                        rj!                  d       d|_        t%        | |        	 d d d        y # 1 sw Y   ^xY w# 1 sw Y   y xY wrv   )r6   rx   ry   rz   r;   r   r   r   r   r   r   r   rK   rc   r   r   r   r   r   r   s       r2   r>   r>      s    		%	%	<	<	> )!%OO$$U$3S5F5Fu5F5U"
 
	)Iv
 ''<<> ;"69c:;&%(("4"45""4( $CC(
	)) ); ;) )s%   A.DD%ADDDDc                   | j                   j                  ^ }}|j                  d   }| j                   j                  |      5  |D ]  }t	        |j
                  d   t        j                        r,t        j                  j                  |j
                  d         sW|j
                  d   }| j                   j                  t        j                  j                  ||j                         f      }|j                  ||        	 ddd       | j                   j!                          | j#                          y# 1 sw Y   4xY w)z
    Make sure the output node's layout does not change due to compiler optimizations
    by adding aten.as_strided nodes with the expected strides.

    Only used for inference so we can assume all graph outputs are model outputs.
    r   valN)r   nodesrg   inserting_beforerc   rM   r6   Tensor_prims_commonis_non_overlapping_and_densecall_functionprimsinductor_force_stride_orderdefaultstridereplace_input_withlintr$   )r%   _output_nodeout_listnftnew_nodes          r2   enforce_output_layoutr      s     hhnnOQ"H		"	";	/ 8 	8Auu||((EEaffUmT Bxx--1199Aryy{;KH **1h7	88$ HHMMOLLN'8 8s   CD99Ec                ^   t         j                  j                  j                  j                  t         j                  j                  j
                  j                  t         j                  j                  j                  j                  g}| j                  j                  D cg c]  }|j                  |v s| }}|D ]  }| j                  j                  |      5  |j                  d   j                  d   }| j                  j                  t        j                  j                  |j                  d   |j!                         f      }|j#                  |j                  d   |       ddd        | j                  j%                          | j'                          yc c}w # 1 sw Y   xY w)z
    Make sure the as_strided node's input's layout does not change due to compiler
    optimizations, because the as_strided strides info depends on input tensor stride info.
    r   r   N)r6   opsaten
as_stridedr   as_strided_as_strided_scatterr   r   targetr   rg   rM   r   r   r   r   r   r   r$   )r%   as_strided_opsr   strided_nodesr   r   s         r2   enforce_as_strided_input_layoutr      s9    			!!))		""**		))11N
 !#M1!((n2LQMMM 6XX&&q) 	6&Bxx--1199AFF1Iryy{;SH   H5	6 	66 HHMMOLLN N	6 	6s   "F6FBF##F,	c           	        t        d      5  | j                  j                  D cg c],  }|j                  t        j
                  j                  k(  s+|. }}|D ]  }|j                  d   }t        |j                  d   j                               dk7  s-|j                  d   j                  t        j                        ri| j                  j                  |      5  | j                  j                  t        j                   j                  |fdt        j                  i      }|j#                  ||       ddd        t%        |        t'        |        ddd       yc c}w # 1 sw Y   xY w# 1 sw Y   yxY w)z
    Convert 4d convolution weight tensor to channels last format.

    This pass is performed before freezing so the added nodes can be constant
    folded by freezing.
    %convert_conv_weights_to_channels_lastr   r      )memory_formatr   N)r   r   r   r   r   convolutionr   rg   r   rM   sizeis_contiguousr6   channels_lastr   r   cloner   r   r   )r%   r   convsconvweight_noder   s         r2   r   r      sI    
=	> "HHNNSqahh$:J:J:R:R.RSS 	?D))A,K;##E*//12a7;;K;K<m%*=*=m><? **40 ?8811JJ&& N$e&9&9:
 ''X>? ?	?  	(+b!'" "S? ?" "s<   E2,E E BE2AE%7 E2 E2%E/*E22E;)r%   torch.fx.GraphModuler&   z	list[Any]r'   z1torch._functorch.aot_autograd.ViewAndMutationMetarl   z	List[int])rA   r   rB   r   rC   z"List[torch._subclasses.FakeTensor]rl   z&Tuple[torch.fx.GraphModule, List[int]])r^   r   )r%   r   ).
__future__r   r   loggingrZ   typingr   r   r   r   r6   torch.utils._pytreerx   _pytreera   torch._dynamo.utilsr   r	   torch._functorch.aot_autogradr
   torch._functorch.compile_utilsr    torch._inductor.constant_foldingr   r   +torch._inductor.fx_passes.freezing_patternsr   #torch._inductor.fx_passes.post_gradr    r   r   r   r   	getLoggerro   r?   r3   rI   r   rK   r=   r>   r   r   r   rn   rW   r2   <module>r      s    "    - -  $ $ D 6 7 V G ?  yy~~		g!$!$!$! C$! 	$!N72#72)72 772 ,	72t
5<< 
4-,)>2"rW   