
    9jN                       d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
 d dlmZm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 d	d
lmZmZ erd dlmZmZ  e       Ze G d d             Z G d dej                   j@                        Z!ddZ"	 	 	 	 	 	 	 	 ddZ#	 	 	 	 	 	 ddZ$ddZ%ddZ&e G d d             Z'e%fdddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ(y)     )annotationsN)	dataclass)partialwraps)AnyTYPE_CHECKING)tqdm)StorageWeakRef)ContentStoreWriter   )get_outputsget_placeholders)CallableSequencec                  6    e Zd ZU ded<   ded<   ded<   ded<   y)	LoadTensorMetaztuple[int, ...]sizestrideztorch.dtypedtypeztorch.devicedeviceN)__name__
__module____qualname____annotations__     \/media/conek/DATA/Code/OCR/venv/lib/python3.12/site-packages/torch/_functorch/fx_minifier.pyr   r      s    
r   r   c                  N     e Zd Zddd	 	 	 	 	 	 	 d fdZd fdZd	 fdZ xZS )
ConcretePropNFwriterskip_offloadc               l    t         |   |       || _        || _        t	               | _        d | _        y N)super__init__r!   r"   setseen_storagespbar)selfmodr!   r"   	__class__s       r   r&   zConcreteProp.__init__$   s2     	(25%	r   c                    | j                   j                  d       t        |   |      }|j                  }t        |t        j                        r| j                  ||j                  d<   |S t        |j                               | j                  v rd |j                  d<   |S | j                  s:| j                  j                  t        j                   j#                  d|      |       t%        |j'                         |j)                         |j*                  |j,                        |j                  d<   | j                  j/                  t        |j                                      |S t0        |j                  d<   |S )Nr   concrete_valueeager)r)   updater%   run_nodename
isinstancetorchTensorr!   metar
   untyped_storager(   r"   write_tensorospathjoinr   r   r   r   r   addis_tuple)r*   nrr2   r,   s       r   r1   zConcreteProp.run_node1   s1   		GQvva&{{"+,'(   "!"3"3"56$:L:LL 04AFF+,   ,,00gt1LaP/=!((*aggqxx0AFF+, &&**>!:K:K:M+NO  (0AFF#$r   c                |   | j                   }t        |t        j                        st	        dt        |             t        dt        |j                  j                        | j                  d u       5 }|| _        t        | 4  | }| j                  s|j                  d       |cd d d        S # 1 sw Y   y xY w)Nzexpected fx.GraphModule, got z(Saving intermediates for delta debugging)desctotaldisablezESaved!  To skip next time, run with --skip-saving-eager-intermediates)moduler3   fxGraphModuleAssertionErrortyper	   lengraphnodesr!   r)   r%   runr"   set_description)r*   argsr+   r)   r?   r,   s        r   	propagatezConcreteProp.propagateJ   s    kk#r~~. #@c!LMM;ciioo&KK4'
 	 DIT"A$$$$[ 	 	 	s   62B22B;)r+   fx.GraphModuler!   zContentStoreWriter | Noner"   boolreturnNone)r>   fx.NoderR   r   )rN   r   rR   r   )r   r   r   r&   r1   rO   __classcell__)r,   s   @r   r   r   #   sE    
 -1" *	
  
2 r   r   c                    | j                   dk(  xr: | j                  t        j                  j                  j
                  j                  u S )Ncall_function)optargetr4   ops
debugprimsload_tensordefault)nodes    r   is_load_tensor_noder_   \   s;    ?" 	DKK599//;;CCCr   c                   |j                   dk(  s|j                   dk(  ryt        |      ry|j                  j                  dd       }t	        |t
        j                        r8d|_         |j                  |_        d|_	        i |_
        |j                  |       y|y|t        u r/d}t        |j                        D ]  }t        | ||      xs |} |S t	        |t               rd|_         t
        j"                  j$                  j&                  j(                  |_        t*        j,                  j/                  d|j                        |j0                  |j2                  f|_	        |j4                  |j6                  d	|_
        yy)
NoutputplaceholderFr.   r   TrW   r/   )r   r   )rX   r_   r6   getr3   r4   r5   r2   rY   rN   kwargsappendr=   listusers_convert_node_to_placeholderr   rZ   r[   r\   r]   r9   r:   r;   r   r   r   r   )rJ   r^   inpsconcrete_valr?   
tuple_users         r   rh   rh   d   sI    ww(dgg64 99==!148L,-ii	L!				!tzz* 	KJ,UJEJA	K 	L.	1!ii**66>>GGLL$)),
	 #))!''
 r   c                    t        j                          d}t        j                  |d       ddlm}  || ||       y)z
    Takes minified FX graph as primary input, and ports it to HLO via StableHLO
    Provides minified HLO graph as output, and archive them to local directory
    z
/hlo_filesT)exist_okr   )save_torch_model_as_stablehloN)r9   getcwdmakedirstorch_xla.stablehlorn   )minified_fx_graphinputshlo_dirrn   s       r   create_minified_hlo_graphru      s4     Z(GKK$'A!"3VWEr   c                    t        dt        | j                  j                         d|D cg c]/  }|j                  |j
                  |j                  j                  f1 c} d| j                   d       y c c}w )Nz
# Working Repro with z nodes
inps = zo
inps = [torch.zeros(())] + [torch.ones(shape, dtype=dtype, device=device) for (shape, dtype, device) in inps]

)	printrI   rJ   rK   shaper   r   rH   code)fx_gri   is      r   
dump_stater}      sn    	$****+, -489q!''177AHHMM	*9: ; 		 	:s   4A7c                $    | dk(  ry| | dz
  z  dk(  S )Nr   Fr   r   )r>   s    r   is_power_of_twor      s    AvQKAr   c                  *    e Zd ZU ded<   ded<   ddZy)
ReproStatefx.GraphrJ   Sequence[torch.Tensor]ri   c                    t        | j                        }t        |      t        | j                        k7  r-t	        dt        |       dt        | j                               y )Nlen(ph_nodes)=z != len(self.inps)=)r   rJ   rI   ri   rG   )r*   ph_nodess     r   __post_init__zReproState.__post_init__   sT    #DJJ/x=C		N*  X/B3tyy>BRS  +r   N)rR   rS   )r   r   r   r   r   r   r   r   r   r      s    O
  r   r   F)save_diroffload_to_diskr"   skip_sanitymax_granularityc          
           j                   }	t        |	j                        }
|t        |      st	        d| d      dd) fdd* fdd}|r|t        d      t        |      } t         ||      j                  |  |s |	|      st	        d	      t        d
|
 dt        j                         	 	 	 	 	 	 d+fd	 	 	 	 d,fd} |d      	 	 	 	 	 	 	 	 d-fd        |d      	 	 	 	 	 	 	 	 d-fd       d.d d. fd	 	 	 	 	 	 	 	 d-fd}  |d      |       |d      	 	 	 	 	 	 	 	 d-fd       	 	 	 	 	 	 d/d |d      	 	 	 	 	 	 	 	 d- fd        |d      	 	 	 	 	 	 	 	 d-fd       t        |	|      }	 	 	 	 	 	 	 	 d0fd}	  |t        j                   |j                         |j                         t!        d t#        j$                  t#        j&                  t        |j                   j                                    z        }|t)        ||      } |||d!      }||}|d z  }d"}|d#k\  r |||d"!      }||}d}n|d z  }|d#k\  r|r |d#      }||}	  |j                   |j                        st	        d$      t        d% d&t        j                         t        j                   |j                         }d't*        j,                  v rt/        ||j                          |||j                         t        d(t        j                         ||j                  fS )1aF  
    Minimizes a FX graph with given inputs, such that the resulting FX graph still returns True for module_fails.

    Does 2 main strategies:
    1. Truncates suffix: Removes some suffix from the graph and sets a new output.
    2. Delta Debugging: Tries replacing half of the graph with inputs. If fails,
        tries replacing quarter of the graph, etc.

    >>> # xdoctest: +SKIP(failing)
    >>> failing_function = fx.symbolic_trace(f)
    >>> minimize(failing_function, [torch.randn(5)], lambda fx_g, inps: fx_g(*inps))

    note: module_fails returns True if it fails.
    Nzmax_granularity z not power of twor   c                j    t        j                  t        j                  |             j                  S r$   )rE   rF   copydeepcopyrJ   )fx_graphfail_fs    r   deepcopy_fx_graphz#minifier.<locals>.deepcopy_fx_graph   s#    ~~fdmmH&=>DDDr   c                    t        j                  |       } dz  t        j                  |       }|j                  j                           ||      S )Nr   )r   r   rE   rF   rJ   lint)rJ   ri   r+   r   module_failsnum_queriess      r   graph_failszminifier.<locals>.graph_fails   sF    e$qnnVU+		C&&r   z3save_dir must not be None when offload_to_disk=Truer    z#Input graph did not fail the testerzStarted off with  nodesfilec                <     t               dd fd       }|S )Nc                X   t        t        j                         t        d d| dt        | j                  j
                         dt        | j                         d	t        j                           
| j                        t        | j                        |      }|it        |j                  j
                        }t        | j                  j
                        }t        |j                        }t        | j                        }t        t        |j                              }t        t        | j                              }d}	||k  r$d}	t        d	| d
| dt        j                         ||kD  r$d}	t        d	| d
| dt        j                         ||k  r$d}	t        d	| d
| dt        j                         |	st        d       |j                  |j                        st        dt        j                         y |S t        d t        j                         y )Nr   z
Strategy: z (G: z) (z nodes, z inputs)FTzSUCCESS: Went from z to r   z inputsz outputsz$Success raised but no progress made?z=WARNING: Something went wrong, not applying this minificationzFAIL: )
rx   sysstderrrI   rJ   rK   ri   rf   r   RuntimeError)	old_stategranularity	new_state	new_nodes	old_nodesnew_inpsold_inpsnew_outsold_outsprogress_mader   r   r2   strategys             r   new_funcz6minifier.<locals>._register_strategy.<locals>.new_func   s   szz"TF%} 5	--./xINN8K7LHVZZ
 !!)//2D4H+I $	 5 56		 5 56	y~~.y~~.{9??;<{9??;< %y($(M-i[YKvN ZZ h&$(M-hZtH:WM ZZ h&$(M-hZtH:XN ZZ
 %&'MNN"9??INNCW ZZ    tfoCJJ7r   )r   )r   r   r   intrR   ReproState | None)r   )r   r2   r   r   r   s   `` r   _register_strategyz$minifier.<locals>._register_strategy   s(     
x1	 1	 
1	f r   c                    t        |       S )N)r2   )r   )r2   r   s    r   register_strategyz#minifier.<locals>.register_strategy6  s     )55r   zTruncate suffixc                  	 t               }t        j                         }i 	t        | j                        D ]  \  }}|j                  |	fd      }|j                  dvr||z  dk(  r||dz  z  dk7  rz||vrv|j                  |f      }t        |j                        t        | j                        k  r 
||      rt        ||      c S |j                  |       |j                  |       |	|<    y )Nc                    |    S r$   r   xenvs    r   <lambda>z1minifier.<locals>.remove_suffix.<locals>.<lambda>F  s    3q6 r   )rb   ra   r      )r'   rE   Graph	enumeraterK   	node_copyrX   ra   rI   r   r<   
erase_node)	cur_graphcur_inpsr   tested	new_graphidxr^   new_nodeoutput_noder   r   s            @r   remove_suffixzminifier.<locals>.remove_suffix>  s     5HHJ	&("9??3 	!IC **41ABHww77 +%*a0A56)"+"2"2H;"?K9??+c)//.BB{!8H  *)X>>

3!,,[9 CI#	!$ r   zRemove outputsc                *   t        d|dz        }d }t        | j                        D ]  \  }}||_        |j                  dk(  s|} n |y t        |j                  d   t        j                        ry |j                  d   }t        |t        t        f      st        dt        |             t        |d       }t        |      dk(  ry t        dt        |      |      D ]-  }|d | |||z   d  z   f|_         | |      s!t!        | |      c S  y )Nr   r   ra   r   z2expected output_args_raw to be list or tuple, got c                d    t        | t        j                        r| j                  S t	        d      S )Ng    eA)r3   rE   Noder   r   )r   s    r   r   z2minifier.<locals>.remove_outputs.<locals>.<lambda>s  s    :a#9!%% s3x r   )key)maxr   rK   r   rX   r3   rN   rE   r   rf   tuplerG   rH   sortedrI   ranger   )	r   r   r   ra   r   r^   output_args_rawoutput_argsr   s	           r   remove_outputsz minifier.<locals>.remove_outputsY  s/    ![A-.!%"9??3 	ICDHww("		 >fkk!nbgg. !++a./D%=9 DT/EZD[\  G
 {q C,k: 	7C&t,{3;L;N/OOQFK9h/!)X66	7 r   c                   | j                   }| j                  }t        t        |            }t	        |      t	        |      k7  r#t        dt	        |       dt	        |             g }t        t	        |            D ]F  }t	        ||   j                        dk(  r|j                  ||          3|j                  ||          H t	        |      t	        |      k  rt        ||      S y )Nr   z != len(cur_inps)=r   )rJ   ri   rf   r   rI   rG   r   rg   r   re   r   )	cur_stater   r   r   r   r   s         r   remove_unused_inputs_uncheckedz0minifier.<locals>.remove_unused_inputs_unchecked~  s    OO	>>(34x=CM)  X/A#h-Q  (*X' 	/C8C=&&'1,$$Xc]3.		/
 x=3x=(i22r   c                X     |       }| |j                   |j                        r|S y r$   )rJ   ri   )r   r   r   r   s     r   remove_unused_inputs_checkedz.minifier.<locals>.remove_unused_inputs_checked  s-    29=	 [)..%Qr   c                (     t        | |            S r$   )r   )r   r   r   r   s      r   _remove_unused_wrapperz(minifier.<locals>._remove_unused_wrapper  s     ,Jy(,KLLr   zRemove unused inputszEliminate dead codec                P    | j                         r | |      rt        | |      S y r$   )eliminate_dead_coder   )r   r   r   r   s      r   r   z%minifier.<locals>.eliminate_dead_code  s*     ((*{9h/Oi22r   c                   t        j                         }i d}| j                  D ]  }|j                  dk(  r|j	                  |fd      }||<   -|st        |      rw|j                  |j                        }||<   |j                  t        j                  j                  j                  j                  |j                  i |j                         d} | j                  D ]!  }|vs|j	                  |fd      }||<   # |S )NFrb   c                    |    S r$   r   r   s    r   r   z=minifier.<locals>._consolidate_placeholders.<locals>.<lambda>      s1v r   Tc                    |    S r$   r   r   s    r   r   z=minifier.<locals>._consolidate_placeholders.<locals>.<lambda>  r   r   )rE   r   rK   rX   r   r_   rb   r2   re   r4   rZ   r[   r\   r]   rN   rd   )r   ri   r   seen_non_placeholderr^   r   r   s         @r   _consolidate_placeholdersz+minifier.<locals>._consolidate_placeholders  s     HHJ	$
 OO 	,Dww-'$..t5EF$D	).A$.G$00;$D	II((44<<diiW4;;W (,$	, OO 	%D3$..t5EF$D		% r   zDelta Debuggingc                
   t        | j                        }t        d||      D ]  }d} |       }t        |d d        }t	        |||z         }t        ||      D ]*  }	t        |j                        |	   }
t        ||
|      s)d}, |sf|j                           ||      } t        ||            }|t        ||      } |j                  |j                        st        |j                  |j                        c S  y )Nr   FT)
rI   rK   r   rf   minrh   r   r   rJ   ri   )r   r   r   	num_nodesstart_rangeis_removingr   r   	end_ranger   r   r   r   r   r   r   s               r   delta_debuggingz!minifier.<locals>.delta_debugging  s    	(	 I{; 	CKK))4IHQK(HI{['@AI[)4 '	05/	8XN"&K' ))+1)XFI6z)X7VWI &y(;	9??INN;!)//9>>BB#	C& r   zConsolidate Inputsc                    t        |      }t        |d d        } | |      } t        |      |kD  r | |      rt        | |      S y r$   )rI   rf   r   )r   r   r   old_lenr   r   r   s        r   consolidate_inputsz$minifier.<locals>.consolidate_inputs  sM     h-$-iB	x=7"{9h'Gi22r   c                *   t        d| t        j                         g }t        | j                  j
                        }t        t        | j                              }||dz  kD  r|gz  }|r|
gz  }|	gz  }|D ]  } || |      }||c S  y )NzTrying granularity r   r   )rx   r   r   rI   rJ   rK   r   )failing_stater   use_non_granular
strategiesr   num_outputsr   r   r   r   r   r   r   remove_unused_inputss           r   try_granularityz!minifier.<locals>.try_granularity  s     	#K=1

C
++112	+m&9&9:;a'>**J#$" J 	}o66
" 	!H <I$  	! r   Tr   )r   Fr   z9Uh oh, something went wrong :( Final graph is not failingzMade z queriesXLA_HLO_DEBUGz#Wrote minimal repro out to repro.py)r   r   rR   r   )rJ   r   ri   r   rR   rQ   )r   zDCallable[[fx.Graph, Sequence[torch.Tensor], int], ReproState | None]r2   strrR   z.Callable[[ReproState, int], ReproState | None])r2   r   rR   zCallable[[Callable[[fx.Graph, Sequence[torch.Tensor], int], ReproState | None]], Callable[[ReproState, int], ReproState | None]])r   r   r   r   r   r   rR   r   )r   r   rR   r   )r   r   ri   list[torch.Tensor]rR   r   )r   r   r   r   r   rQ   rR   r   )rJ   rI   rK   r   r   rG   r   r   rO   rx   r   r   r   rE   rF   ri   r   mathfloorlog2r   r9   environru   )!r   ri   r   r}   r   r   r"   r   r   failing_graphcur_sizer!   r   r   r   r   r   r   has_progress
failing_fxr   r   r   r   r   r   r   r   r   r   r   r   r   s!   ` `                 @@@@@@@@@@@@@r   minifierr      sY   6 LLM=&&'H"??+K-o->>OPQQKE' F !VWW#H-LL\BLLdS{=$?@AA	hZv
.SZZ@8V88 
88t66
6 ()'=LO	 *4 '(""'="LO"	" )"H&MM'=MLOM	M
 E,-CD ,-'=LO	 .#5	< ()'=LO	 *2 +,'=LO	 - }d3M!03GK	 4 2>>&-*=*=>@R@RS!

499S9L9L9R9R5S+T UVW&o{;K#M;QUV	 %MQ'{UI $ )#AK Q "=!4	 %M}**M,>,>?VWW	E+h
'cjj9(;(;<J "**$!*m.@.@Az=--.	
/cjjA}))))r   )r^   rT   rR   rQ   )rJ   r   r^   rT   ri   r   rR   rQ   )rr   rP   rs   r   rR   rS   )r{   rP   ri   r   rR   rS   )r>   r   rR   rQ   )r   rP   ri   r   r   z8Callable[[fx.GraphModule, Sequence[torch.Tensor]], bool]r}   z8Callable[[fx.GraphModule, Sequence[torch.Tensor]], None]r   z
str | Noner   rQ   r"   rQ   r   rQ   r   z
int | NonerR   z-tuple[fx.GraphModule, Sequence[torch.Tensor]]))
__future__r   r   r   r9   r   dataclassesr   	functoolsr   r   typingr   r   r4   torch.fxrE   	torch.hubr	    torch.multiprocessing.reductionsr
   torch.utils._content_storer   compile_utilsr   r   collections.abcr   r   objectr=   r   Interpreterr   r_   rh   ru   r}   r   r   r   r   r   r   <module>r     so   "   	 
 ! $ %    ; 9 8 2 8   6588'' 6r//"/*</	/dF%F/EF	F 	 	 	  LV	o*  !"&o*o*
 o* Ko* I	o* o* o* o* o*  o* 3o*r   