
    Vh                     L   d dl mZ d dlZd dlmZmZmZ d dlmZm	Z	 d dl
mZ ej                  j                  Zej                  ej                  ej                   ej"                  ej$                  ej&                  ej(                  ej*                  ej,                  ej.                  ej0                  ej2                  ej4                  ej6                  ej8                  hZej<                  ej>                  ej@                  ejB                  ejD                  ejF                  ejH                  ejJ                  ejL                  h	Z'ejP                  jR                  jU                  d      d        Z+ejP                  jR                  jU                  d       G d	 d
e             Z,y)    )AnyN)GraphGraphModuleNode)PassBase
PassResult)tree_flattenF)is_backward_compatiblec                  4    t         j                  t              S N)rand_opsunioninplace_ops     W/home/dcms/DCMS/lib/python3.12/site-packages/torch/fx/passes/dialect/common/cse_pass.pyget_CSE_banned_opsr   -   s    >>+&&r   c                   0     e Zd Zd fd	ZdedefdZ xZS )CSEPassc                 H    |
t               }|| _        t        |           y)a  
        This version of CSE Pass aims to be dialect agnostic, and it's implemented purely based on the connectivity between fx.Node.

        For functional dialects, user would only need to specify the random ops in ban list.

        Warning: CSE Pass cannot be safely applied on a FX graph in non-functional dialects.
        If your dialect contains stateful operators, please customized the banned_ops.

        N)set
banned_opssuper__init__)selfr   	__class__s     r   r   zCSEPass.__init__4   s$     J$r   graph_modulereturnc                    d }d}t               }i i }i }|j                  j                  D ]  }|j                  dk(  s2|j                  dk(  s#|j                  dk(  s ||      | j                  v r|j                  |fd      }||<   _fd}	 |	|j                        \  }
} |	|j                        \  }}|j                  |
|||d}t        |
|f      }|j                  |f}||v }|r||   |k(  rd	}||   |<   |j                  |fd
      }||<   |r|||<   |||<    t        ||      }t        ||      S )a  
        Return a new copy of torch.fx.GraphModule with CSE applied to the input graph

        Example usage:

        from torch.fx.experimental.proxy_tensor import make_fx
        def f(a):
            b = a * a
            c = a * a
            return b+c

        p = CSEPass()
        traced_graph = make_fx(f)(torch.tensor(1))
        print(traced_graph)
        result = p(traced_graph)
        print(result.graph_module)
        c                 r    t        | j                  d      r| j                  j                  S | j                  S )Noverloadpacket)hasattrtargetr!   )nodes    r   get_aten_targetz%CSEPass.call.<locals>.get_aten_targetV   s+    t{{$45{{111;;r   Fplaceholderoutputget_attrc                     |    S r   r   xenvs    r   <lambda>zCSEPass.call.<locals>.<lambda>o       CF r   c                     t        |       \  } }t        t        |             D ]%  }| |   }t        |t              s|v s|   | |<   ' t        |       |fS r   )r	   rangelen
isinstancer   tuple)arg_listspecivr,   s       r   
substitutez CSEPass.call.<locals>.substitutet   s`    %1(%;NHd"3x=1 1$QK%a.18*-a&HQK1 !?D00r   )r#   args	args_speckwargskwargs_specTc                     |    S r   r   r*   s    r   r-   zCSEPass.call.<locals>.<lambda>   r.   r   )r   graphnodesopr   	node_copyr9   r;   r#   hashr   r   )r   r   r%   modified	new_graphhash_env	token_mapnnew_noder8   r9   r:   r;   r<   tokenhash_arghash_valhash_val_in_hash_envcsed_gmr,   s                      @r   callzCSEPass.callC   s   &	
 G	  	
  	
  	 ##)) 2	0A %448#44:%"1%8$..q2BC!A1 #-QVV"4i&0&:#
  hh !*$#.  v/HHh/ (08';$'Ih,?5,H#H%h/CF$..q2BC!A+)1HX&*/Ih'e2	0h lI6'8,,r   r   )__name__
__module____qualname__r   r   r   rN   __classcell__)r   s   @r   r   r   2   s    X- X- X-r   r   )-typingr   torchtorch.fxr   r   r   torch.fx.passes.infra.pass_baser   r   torch.utils._pytreer	   opsatendropout_fused_dropout_standard_gamma	bernoullimultinomialnative_dropoutnormalpoissonbinomialrrelu	rand_likerandrandintrandnrandpermr   add_sub_mul_div_pow_lerp_relu_sigmoid_tanh_r   fx_compatibilitycompatibilityr   r   r   r   r   <module>ru      sL     - - @ , yy~~
 	LLNNKKLLMMJJNNIILLJJMM& 	IIIIIIIIIIJJJJMMJJ
 &&e&D' E' &&e&Dh-h h- Eh-r   