a
    h1                     @   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ejjedd	d
ZejjeedddZdeejjejjf eeejjgef  eedddZdS )    N)CallableOptionalUnion)map_arg)split_module)FoldedGraphModuleget_unique_attr_name_in_modulesplit_const_subgraphsc                       sX   e Zd ZdZdejjejje	ejj e	e
 e
d 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__ N/var/www/auris/lib/python3.9/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r`tj fdd|D n |}tj| d S )NTc                    sJ   t jjt| ts|   nt | gj j	dt| t jrB| j
nddS )N)ZdeviceF)requires_grad)r   nn	Parameter
isinstanceintdetachcloneZ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       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   ZGraphr   strr   r   r   __classcell__r   r   r   r   r      s      
r   )gminline_mod_namec              	      s:  t |  | }t|tjjs"J d}| jjD ] }|jdkr.|j	|kr.|} qPq.|dus\J |j
}|j}i  d} fdd}|jjD ]}	|	jdkr|	j|v r||	j n||  |	< |d7 }q|	jdkr|	j
d }
t|
|}|| q| j| | j|	|}W d   n1 s0    Y  | |	< q| 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Zreplacement_mappingr   r   replacement_fnj   s    z&_inline_module.<locals>.replacement_fnplaceholder   output)dictZnamed_modulesr$   r   r   r   r   nodesoptargetr   r    namer   replace_all_uses_withinserting_beforeZ	node_copyeliminate_dead_code)r:   r;   Z
inline_modZcall_mod_node_to_replacer?   Zcall_mod_argsZcall_mod_kwargsZph_countrB   Zinline_nodeoutputsZoutput_replacementsr@   r   rA   r   _inline_moduleS   s<    




.
rO   )
mod_tracedrJ   returnc                 C   sx   t dd|}|d  r$d| }t| |rtt d|}|du rL|d }q$|dd\}}| dt|d  }q$|S )	zP
    Make sure the name is unique (in a module) and can represents an attr.
    z[^0-9a-zA-Z_]+_r   z(.*)_(\d+)$NZ_1rD      )resubisdigithasattrmatchgroupr%   )rP   rJ   rX   basenumr   r   r   r      s    


r   cpu)moduleskip_folding_node_fnr   rQ   c              	      s^  t | tjjstj| }n| }t  d}|jjD ]\}|jdv rBq2|jdkr^t|j	
 s^q2|rl||rlq2| rvq2 | |jdkr2d}q2|st||jS tjjd fdd}t|| |}d\}}	|jt||	d	 }
}|r|jjng D ]$}|jd
krt||jt||j q|
jjD ](}|jd
krt||jt|
|j qd	}|jjD ]*}|jd
krR|j|krR|j} q~qR|d	usJ tj||
j}d}|jjD ]}|jdkrt |jd t}q|jdkrܐq|t|k sJ || }|d7 }|jdksJ |j| |j|j}W d	   n1 s@0    Y  |j |_|| |j| qdt v sJ t|d}t|||rtj  ntj!  |jjD ]t}|jd
kr|j|kr|j| |j|}W d	   n1 s 0    Y  |j |_||  q*qt"||	r@t#||	 |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>   rE   rC   get_attrTr?   c                    s   |  v rdS dS )Nr   rD   r   r`   Zconst_nodesr   r   mod_partition   s    z,split_const_subgraphs.<locals>.mod_partition)submod_0Zsubmod_1Nr<   r   rE   rC   rD   multiple_outputsZ_FX_CONST_FOLDED_ATTRS)%r$   r   r   r   Zsymbolic_tracesetr   rG   rH   Zall_input_nodesissubsetZ	is_impureaddr   Noder   rc   getattrr0   rI   r   r.   lenrL   r_   r=   r>   rK   Z
erase_nodelocalsr   r"   r/   r#   rW   rO   rM   )r]   r^   r   rP   Zfound_const_foldingr?   rb   splitZconst_mod_nameZnon_const_mod_nameZconst_gmZnon_const_gmZcall_const_gm_argsZroot_const_gmZph_idxrd   Zin_noder@   r   r1   r   ra   r   r	      s    




.
,



r	   )Nr\   )rT   typingr   r   r   Ztorch.fxr   Ztorch.fx.noder   Ztorch.fx.passes.split_moduler   __all__r   r   r   r8   rO   r   r"   r7   rh   boolr	   r   r   r   r   <module>   s    B4  