o
    Hh<0                  	   @   s   d dl Z d dlmZmZmZ d dlZd dlmZ d dl	m
Z
 g dZG dd dejjZdejjd	efd
dZdejjdedefddZ		ddeejjejjf deeejjgef  dedefddZdS )    N)CallableOptionalUnion)map_arg)split_module)FoldedGraphModuleget_unique_attr_name_in_modulesplit_const_subgraphsc                       sf   e Zd ZdZ			ddejjdejjde	ejj de	e
 de
f
 fd	d
Z fddZdd Z  ZS )r   a  
    FoldedGraphModule is a GraphModule which also contains another
    `const_subgraph_module` representing a subgraph which has all const attr
    inputs and which can be run once before running the main standard
    `graph`. The `const_output_names` are the ordered list names of attrs which
    represent what each respective output from the const_subgraph should be set
    on which attrs.
    Ncudarootgraphconst_subgraphfx_const_folded_attrs_namedevice_for_folded_attrsc                    s@   t  || |d u rd ntj||| _d| _|| _|| _d S )NF)	super__init__torchfxGraphModuleconst_subgraph_modulehas_folding_been_runr   r   )selfr   r   r   r   r   	__class__ T/var/www/vscode/kcb/lib/python3.10/site-packages/torch/fx/experimental/const_fold.pyr      s   
zFoldedGraphModule.__init__c                    s   | j s|   t j| S N)r   run_foldingr   __call__)r   argskwargsr   r   r   r   -   s   zFoldedGraphModule.__call__c                    sz   j d u s
jd u rd S jrJ d_  }fdd t|tr0tj fdd|D n |}tj| d S )NTc                    sN   t jjt| ts|   n
t | gj j	dt| t jr#| j
dS ddS )N)deviceF)requires_grad)r   nn	Parameter
isinstanceintdetachcloneTensortor   r"   )i)r   r   r   _create_paramC   s   z4FoldedGraphModule.run_folding.<locals>._create_paramc                    s   g | ]} |qS r   r   ).0r+   )r,   r   r   
<listcomp>L   s    z1FoldedGraphModule.run_folding.<locals>.<listcomp>)	r   r   r   r%   tupler   r#   ParameterListsetattr)r   folded_attrsparamsr   )r,   r   r   r   2   s   



zFoldedGraphModule.run_folding)NNr
   )__name__
__module____qualname____doc__r   r#   Moduler   Graphr   strr   r   r   __classcell__r   r   r   r   r      s$    
r   gminline_mod_namec              	      s8  t |  | }t|tjjsJ d}| jjD ]}|jdkr'|j	|kr'|} nq|dus.J |j
}|j}i  d} fdd}|jjD ]R}	|	jdkr^|	j|v rS||	j n||  |	< |d7 }qB|	jdkrs|	j
d }
t|
|}|| qB| j| | j|	|}W d   n1 sw   Y  | |	< qB| j  dS )	z
    Given `gm` and some graph module which is called with target name `inline_mod_name`,
    this helper will inline all of the nodes from that called graph module into `gm`.
    Ncall_moduler   c                    s    |  }| j  |_ |S r   )metacopy)nodenew_nodereplacement_mappingr   r   replacement_fnj   s   z&_inline_module.<locals>.replacement_fnplaceholder   output)dictnamed_modulesr%   r   r   r   r   nodesoptargetr   r    namer   replace_all_uses_withinserting_before	node_copyeliminate_dead_code)r<   r=   
inline_modcall_mod_node_to_replacerA   call_mod_argscall_mod_kwargsph_countrE   inline_nodeoutputsoutput_replacementsrB   r   rC   r   _inline_moduleS   s@   







r[   
mod_tracedrN   returnc                 C   s   t dd|}|d  rd| }t| |r>t d|}|du r&|d }n|dd\}}| dt|d  }t| |s|S )	zP
    Make sure the name is unique (in a module) and can represents an attr.
    z[^0-9a-zA-Z_]+_r   z(.*)_(\d+)$N_1rG      )resubisdigithasattrmatchgroupr&   )r\   rN   re   basenumr   r   r   r      s   



r   cpumoduleskip_folding_node_fnr   c              	      s2  t | tjjstj| }n| }t  d}|jjD ].jdv r!qjdkr/tj	
 s/q|r6|r6q r;q  jdkrGd}q|sPt||jS dtjjf fdd}t|| |}d\}}|jt||d	}	}
|
ru|
jjng D ]jd
krt|jt|
j qw|	jjD ]jd
krt|jt|	j qd	}|jjD ]jd
krj|krj} nq|d	usJ tj||	j}|jjD ]Wjdkrt jd t}qˈjdkrqtfdd|D }|jdksJ |j |j|j}W d	   n	1 sw   Y  j |_| |j qdt v s+J t|d}t|||r;tj  ntj!  |jjD ]9jd
kr}j|kr}j j|}W d	   n	1 skw   Y  j |_|  nqEt"||rt#|| |j$  t||j|j||S )aJ  
    Looks through `module` for any nodes that have all constant attribute inputs
    and separates them out into their own constant subgraph, and returns a
    FoldedGraphModule which runs that constant subgraph on the first run to set
    attributes on the module prior to running the non-constant portion of the
    graph.
    F>   rH   rF   get_attrTrA   c                    s   |  v rdS dS )Nr   rG   r   rA   )const_nodesr   r   mod_partition   s   z,split_const_subgraphs.<locals>.mod_partition)submod_0submod_1Nr>   rH   r   rF   c                 3   s     | ]}|j  jkr|V  qd S r   )rN   rM   )r-   nrm   r   r   	<genexpr>  s    z(split_const_subgraphs.<locals>.<genexpr>multiple_outputs_FX_CONST_FOLDED_ATTRS)%r%   r   r   r   symbolic_tracesetr   rK   rL   all_input_nodesissubset	is_impureaddr   Noder   rp   getattrr1   rM   r   r/   nextrP   rl   r?   r@   rO   
erase_nodelocalsr   r#   r0   r$   rd   r[   rR   )rj   rk   r   r\   found_const_foldingro   splitconst_mod_namenon_const_mod_nameconst_gmnon_const_gmcall_const_gm_argsroot_const_gmrt   in_noderB   r   r2   r   )rn   rA   r   r	      s   












r	   )Nri   )ra   typingr   r   r   torch.fxr   torch.fx.noder   torch.fx.passes.split_moduler   __all__r   r   r   r:   r[   r   r#   r8   r|   boolr	   r   r   r   r   <module>   s(   B4