o
    IhC                     @   s   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
 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 ZeG d
d dZG d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 dZ!efdddddddej"de
fddZ#dS )    N)	dataclass)partialwraps)Callable)tqdm)StorageWeakRef)ContentStoreWriter   )get_outputsget_placeholdersc                   @   s:   e Zd ZU ee ed< ee ed< ejed< ejed< dS )LoadTensorMetasizestridedtypedeviceN)	__name__
__module____qualname__listint__annotations__torchr   r    r   r   P/var/www/vscode/kcb/lib/python3.10/site-packages/torch/_functorch/fx_minifier.pyr      s
   
 
r   c                       s<   e Zd Zddd fdd
Z fddZ fdd	Z  ZS )
ConcretePropNFwriterskip_offloadc                   s$   t  | || _|| _t | _d S N)super__init__r   r   setseen_storages)selfmodr   r   	__class__r   r   r        s   zConcreteProp.__init__c                    s   | j d t |}|j}t|tjr\| jd u r!||j	d< |S t
| | jv r1d |j	d< |S | js@| jtjd|| t| | |j|j|j	d< | jt
|  |S t|j	d< |S )Nr	   concrete_valueeager)pbarupdater   run_nodename
isinstancer   Tensorr   metar   untyped_storager"   r   write_tensorospathjoinr   r   r   r   r   addis_tuple)r#   nrr,   r%   r   r   r+   &   s&   




zConcreteProp.run_nodec                    sh   t dt| jjj| jd u d}|| _t j| }| j	s!|
d |W  d    S 1 s-w   Y  d S )Nz(Saving intermediates for delta debugging)desctotaldisablezESaved!  To skip next time, run with --skip-saving-eager-intermediates)r   lenmodulegraphnodesr   r)   r   runr   set_description)r#   argsr)   r8   r%   r   r   	propagate?   s   $zConcreteProp.propagate)r   r   r   r    r+   rC   __classcell__r   r   r%   r   r      s    r   c                 C   s   | j dko| jtjjjju S )Ncall_function)optargetr   ops
debugprimsload_tensordefault)noder   r   r   is_load_tensor_nodeN   s   
rM   c                 C   s   |j dks
|j dkrdS t|rdS |jdd }t|tjr3d|_ |j|_d|_	i |_
|| dS |d u r9dS |tu rQd}t|jD ]
}t| ||pM|}qD|S t|trxd|_ tjjjj|_tjd|j|j|jf|_	|j|jd	|_
dS dS )
NoutputplaceholderFr'   r   TrE   r(   )r   r   )rF   rM   r/   getr-   r   r.   r,   rG   rB   kwargsappendr6   r   users_convert_node_to_placeholderr   rH   rI   rJ   rK   r2   r3   r4   r   r   r   r   )r>   rL   inpsconcrete_valr8   
tuple_userr   r   r   rT   V   s>   

rT   c                 C   s8   t   d}t j|dd ddlm} || || dS )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)	exists_okr   )save_torch_model_as_stablehloN)r2   getcwdmakedirstorch_xla.stablehlorY   )minified_fx_graphinputshlo_dirrY   r   r   r   create_minified_hlo_graph   s   r`   c                 C   s4   t dt| jj ddd |D  d| j d d S )Nz
# Working Repro with z nodes
inps = c                 S   s   g | ]}|j |j|jjfqS r   )shaper   r   type).0ir   r   r   
<listcomp>   s    zdump_state.<locals>.<listcomp>zo
inps = [torch.zeros(())] + [torch.ones(shape, dtype=dtype, device=device) for (shape, dtype, device) in inps]

)printr<   r>   r?   code)fx_grU   r   r   r   
dump_state   s   
rj   c                 C   s   | dkrdS | | d @ dkS )Nr   Fr	   r   )r7   r   r   r   is_power_of_two   s   rk   c                   @   s.   e Zd ZU ejed< eej ed< dd Z	dS )
ReproStater>   rU   c                 C   s$   t | j}t|t| jksJ d S r   )r   r>   r<   rU   )r#   ph_nodesr   r   r   __post_init__   s   
zReproState.__post_init__N)
r   r   r   fxGraphr   r   r   r.   rn   r   r   r   r   rl      s   
 
rl   F)save_diroffload_to_diskr   skip_sanitymax_granularityfail_fc                   s   t |ttfs	J j}	t|	j}
|dur!t|s!td| dd	fdd	fddd}|r9t|}t	||d	j
|  |sN|	|sNtd
td|
 dtjd dtdtffdddtffdd}|dfdd|dfdd
dtfdddtffddfdd }|d!||d"fd#d$d%d&  |d'd(tjf fd)d*|d+ fd,d-t|	|}
fd.d/}	 |t|j|j td1ttt|jj }|durt||}|||d0d2}|dur|}q|d1 }d3}|d4kr2|||d3d2}|dur)|}d0}n	|d1 }|d4ks|r6qو
|d4}|durC|}q	 |j|jsPtd5td6	 d7tjd t|j}d8tjv rnt||j |||j td9tjd ||jfS ):aF  
    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                    s   t  t| jS r   )ro   GraphModulecopydeepcopyr>   )fx_graph)ru   r   r   deepcopy_fx_graph   s   z#minifier.<locals>.deepcopy_fx_graphc                    s2   t | } d7 t | }|j  ||S )Nr	   )rw   rx   ro   rv   r>   lint)r>   rU   r$   )ru   module_failsnum_queriesr   r   graph_fails   s
   


zminifier.<locals>.graph_failsr   z#Input graph did not fail the testerzStarted off with  nodesfilestrategyr,   c                    s&   t ddtf fdd}|S )Nr	   	old_statec           
   
      sn  t tjd t d d| dt| jj dt| j d	tjd  | jt| j|}|d urt|jj}t| jj}t|j}t| j}tt|j}tt| j}d}	||k rkd}	t d	| d
| dtjd ||krd}	t d	| d
| dtjd ||k rd}	t d	| d
| dtjd |	st	d|j|jst dtjd d S |S t d tjd d S )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: )
rg   sysstderrr<   r>   r?   rU   r   r
   RuntimeError)
r   granularity	new_state	new_nodes	old_nodesnew_inpsold_inpsnew_outsold_outsprogress_made)rz   r~   r,   r   r   r   new_func   sb   


z6minifier.<locals>._register_strategy.<locals>.new_func)r	   )r   rl   )r   r,   r   )rz   r~   )r,   r   r   _register_strategy   s   3z$minifier.<locals>._register_strategyc                    s   t  | dS )Nr,   )r   r   )r   r   r   register_strategy  s   z#minifier.<locals>.register_strategyzTruncate suffixc           	         s   t  }t }i  t| jD ]O\}}|| fdd}|jdvrY|| dkrY||d  dkrY||vrY||f}t|jt| jk rO||rOt	||  S |
| || | |< qd S )Nc                        |  S r   r   xenvr   r   <lambda>&      z1minifier.<locals>.remove_suffix.<locals>.<lambda>)rO   rN   r      )r!   ro   rp   	enumerater?   	node_copyrF   rN   r<   rl   r5   
erase_node)		cur_graphcur_inpsr   tested	new_graphidxrL   new_nodeoutput_noder~   r   r   remove_suffix   s$   



zminifier.<locals>.remove_suffixzRemove outputsc                    s   t d|d }t| jD ]\}}||_|jdkr|} nqt|jd tjr(d S t	|jd dd d}t
|dkr;d S tdt
||D ]}|d | ||| d   f|_ | |rat| |  S qCd S )Nr	   r   rN   r   c                 S   s   t | tjr	| jS tdS )Ng    eA)r-   ro   Noder   r   r   r   r   r   r   F  s    z2minifier.<locals>.remove_outputs.<locals>.<lambda>)key)maxr   r?   r   rF   r-   rB   ro   r   sortedr<   rangerl   )r   r   r   r   rL   rN   output_argsr   r   r   remove_outputs9  s(   
 
z minifier.<locals>.remove_outputs	cur_statec                 S   s   | j }| j}t|}t|t|ksJ g }tt|D ]}t|| jdkr/|||  q|||  qt|t|k rDt||S d S )Nr   )	r>   rU   r   r<   r   rS   r   rR   rl   )r   r   r   rm   r   r   r   r   r   remove_unused_inputs_uncheckedQ  s   
z0minifier.<locals>.remove_unused_inputs_uncheckedc                    s&   | }|d ur |j |jr|S d S r   )r>   rU   )r   r   )r~   r   r   r   remove_unused_inputs_checkeda  s   z.minifier.<locals>.remove_unused_inputs_checkedc                    s    t | |S r   )rl   r   r   r   )r   r   r   _remove_unused_wrapperg  s   z(minifier.<locals>._remove_unused_wrapperzRemove unused inputszEliminate dead codec                    s    |   r | |rt| |S d S r   )eliminate_dead_coderl   r   r   r   r   r   n  s   
z%minifier.<locals>.eliminate_dead_codec                    s   t  }i  d}| jD ]9}|jdkr!|| fdd}| |< q|sBt|rB||j}| |< |t	j
jjj|ji |j qd}q| jD ]}| vr\|| fdd}| |< qH|S )NFrO   c                    r   r   r   r   r   r   r   r   ~  r   z=minifier.<locals>._consolidate_placeholders.<locals>.<lambda>Tc                    r   r   r   r   r   r   r   r     r   )ro   rp   r?   rF   r   rM   rO   r,   rR   r   rH   rI   rJ   rK   rB   rQ   )r   rU   r   seen_non_placeholderrL   r   r   r   r   _consolidate_placeholderst  s(   



z+minifier.<locals>._consolidate_placeholderszDelta Debuggingr   c                    s   t | j}td||D ]X}d}| }|d d  }t||| }t||D ]}	t|j|	 }
t||
|r6d}q%|s:q|   ||}t||}|d u rSt||}|j|j	rct|j|j	  S qd S )Nr   FT)
r<   r?   r   minr   rT   r   rl   r>   rU   )r   r   r   	num_nodesstart_rangeis_removingr   r   	end_ranger   r   r   )r   rz   r~   r   r   r   delta_debugging  s,   


z!minifier.<locals>.delta_debuggingzConsolidate Inputsc                    s6   t |} | |} t ||kr| |rt| |S d S r   )r<   rl   )r   r   r   old_len)r   r~   r   r   consolidate_inputs  s
   

z$minifier.<locals>.consolidate_inputsc                    s   t d| tjd g }t| jj}tt| j}||d kr$|g7 }|r-| g7 }|g7 }|D ]}|| |}|d urD|  S q5d S )NzTrying granularity r   r   )rg   r   r   r<   r>   r?   r
   )failing_stater   use_non_granular
strategiesr   num_outputsr   r   )r   r   r   r   r   remove_unused_inputsr   r   try_granularity  s&   

z!minifier.<locals>.try_granularityTr   )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-   tupler   r>   r<   r?   rk   r   r   r   rC   rg   r   r   r   strrl   ro   rp   rv   rU   r   mathfloorlog2r   r2   environr`   )ru   rU   r|   rj   rq   rr   r   rs   rt   failing_graphcur_sizer   r   r   r   r   r   r   has_progress
failing_fxr   )r   r   r   rz   r   r   ru   r~   r|   r}   r   r   r   r   r   r   minifier   s   
7
 




	


r   )$rw   r   r2   r   dataclassesr   	functoolsr   r   typingr   r   torch.fxro   	torch.hubr    torch.multiprocessing.reductionsr   torch.utils._content_storer   compile_utilsr
   r   objectr6   r   Interpreterr   rM   rT   r`   rj   rk   rl   rv   r   r   r   r   r   <module>   sH   /0