o
    ZhC                     @   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   K/var/www/auris/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   Zuntyped_storager"   r   Z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)Z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)   r6   r%   r   r   	propagate?   s   $zConcreteProp.propagate)r   r   r   r    r+   r@   __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   
rJ   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   TrB   r(   )r   r   )rC   rJ   r/   getr-   r   r.   r,   rD   r?   kwargsappendr4   r   users_convert_node_to_placeholderr   rE   rF   rG   rH   r0   r1   r2   r   r   r   r   )r;   rI   inpsZconcrete_valr6   Z
tuple_userr   r   r   rQ   V   s>   

rQ   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)Z	exists_okr   )save_torch_model_as_stablehloN)r0   getcwdmakedirsZtorch_xla.stablehlorS   )Zminified_fx_graphZinputsZhlo_dirrS   r   r   r   create_minified_hlo_graph   s   rV   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]

)printr9   r;   r<   code)Zfx_grR   r   r   r   
dump_state   s   
r_   c                 C   s   | dkrdS | | d @ dkS )Nr   Fr	   r   )r5   r   r   r   is_power_of_two   s   r`   c                   @   s.   e Zd ZU ejed< eej ed< dd Z	dS )
ReproStater;   rR   c                 C   s$   t | j}t|t| jksJ d S r   )r   r;   r9   rR   )r#   ph_nodesr   r   r   __post_init__   s   
zReproState.__post_init__N)
r   r   r   fxGraphr   r   r   r.   rc   r   r   r   r   ra      s   
 
ra   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   )rd   GraphModulecopydeepcopyr;   )Zfx_graph)rj   r   r   deepcopy_fx_graph   s   z#minifier.<locals>.deepcopy_fx_graphc                    s2   t | } d7 t | }|j  ||S )Nr	   )rl   rm   rd   rk   r;   Zlint)r;   rR   r$   )rj   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 )Nrs   z
Strategy: z (G: z) (z nodes, z inputs)FTzSUCCESS: Went from z to rr   z inputsz outputsz$Success raised but no progress made?z=WARNING: Something went wrong, not applying this minificationzFAIL: )
r]   sysstderrr9   r;   r<   rR   r   r
   RuntimeError)
rv   granularity	new_stateZ	new_nodesZ	old_nodesnew_inpsZold_inpsZnew_outsZold_outsZprogress_made)rn   rq   r,   ru   r   r   new_func   sb   


z6minifier.<locals>._register_strategy.<locals>.new_func)r	   )r   ra   )ru   r,   r}   )rn   rq   )r,   ru   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>)rL   rK   r      )r!   rd   re   	enumerater<   	node_copyrC   rK   r9   ra   r3   
erase_node)		cur_graphcur_inpsrz   Ztested	new_graphidxrI   new_nodeZoutput_noderq   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   rK   r   c                 S   s   t | tjr	| jS tdS )Ng    eA)r-   rd   Noder   r   r   r   r   r   r   F  s    z2minifier.<locals>.remove_outputs.<locals>.<lambda>)key)maxr   r<   r   rC   r-   r?   rd   r   sortedr9   rangera   )r   r   rz   r   rI   rK   Z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;   rR   r   r9   r   rP   r   rO   ra   )r   r   r   rb   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;   rR   )r   r{   )rq   r   r   r   remove_unused_inputs_checkeda  s   z.minifier.<locals>.remove_unused_inputs_checkedc                    s    t | |S r   )ra   r   r   rz   )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_codera   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 )NFrL   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   )rd   re   r<   rC   r   rJ   rL   r,   rO   r   rE   rF   rG   rH   r?   rN   )r   rR   r   Zseen_non_placeholderrI   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)
r9   r<   r   minr   rQ   r   ra   r;   rR   )r   r   rz   	num_nodesZstart_rangeZis_removingr   r|   Z	end_ranger   r   r{   )r   rn   rq   r   r   r   delta_debugging  s,   


z!minifier.<locals>.delta_debuggingzConsolidate Inputsc                    s6   t |} | |} t ||kr| |rt| |S d S r   )r9   ra   )r   r   rz   Zold_len)r   rq   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 rs   r   )r]   rw   rx   r9   r;   r<   r
   )failing_staterz   use_non_granular
strategiesr   Znum_outputsru   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 queriesZXLA_HLO_DEBUGz#Wrote minimal repro out to repro.py)r-   tupler   r;   r9   r<   r`   ry   r   r   r@   r]   rw   rx   r   strra   rd   re   rk   rR   r   mathfloorlog2r   r0   environrV   )rj   rR   ro   r_   rf   rg   r   rh   ri   Zfailing_graphZcur_sizer   r   r   r   r   rz   r{   Zhas_progressZ
failing_fxr   )r   r~   r   rn   r   r   rj   rq   ro   rp   r   r   r   r   r   r   minifier   s   
7
 




	


r   )$rl   r   r0   rw   dataclassesr   	functoolsr   r   typingr   r   Ztorch.fxrd   Z	torch.hubr   Z torch.multiprocessing.reductionsr   Ztorch.utils._content_storer   Zcompile_utilsr
   r   objectr4   r   ZInterpreterr   rJ   rQ   rV   r_   r`   ra   rk   r   r   r   r   r   <module>   sH   /0