U
    *-em.                     @   s   d dl Z d dlmZmZmZmZmZ d dlZd dl	m
Z
 d dlmZ dddg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DictOptionalSet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 k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__ a/var/www/html/Darija-Ai-Train/env/lib/python3.8/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 ksjd krd S jr"td_  }fdd t|tr`tj fdd|D n |}t	j| d S )NTc                    sB   t jjt| ts| nt | gj jdt| t jr:| jnddS )N)ZdeviceF)requires_grad)	r   nn	Parameter
isinstanceintZTensortor   r#   )i)r   r   r   _create_param=   s    z4FoldedGraphModule.run_folding.<locals>._create_paramc                    s   g | ]} |qS r   r   ).0r)   )r*   r   r   
<listcomp>F   s     z1FoldedGraphModule.run_folding.<locals>.<listcomp>)
r   r   r   AssertionErrorr&   tupler   r$   ParameterListsetattr)r   folded_attrsparamsr   )r*   r   r   r   ,   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      
)gminline_mod_namec              
      s
  t |  | }t|tjjs"td}| jjD ] }|j	dkr.|j
|kr.|} qPq.|dk	s\t|j}i  d} fdd}|jjD ]|}|j	dkr||  |< |d7 }q~|j	dkr|jd }	t|	|}
||
 q~| j| | j||}W 5 Q R X | |< 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_fnb   s    z&_inline_module.<locals>.replacement_fnplaceholder   output)dictZnamed_modulesr&   r   r   r   r-   r   nodesoptargetr!   r   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ph_countrB   Zinline_nodeoutputsZoutput_replacementsr@   r   rA   r   _inline_moduleM   s4    





rN   )
mod_tracednamereturnc                 C   sx   t dd|}|d  r$d| }t| |rtt d|}|dk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'   )rO   rP   rX   basenumr   r   r   r
   z   s    


cpu)moduleskip_folding_node_fnr   rQ   c              
      s  t | tjjstj| }n| }t  d}|jjD ]\jdk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|| |}|j|j }}d\}	}
|jj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rDj|	krDj} qpqD|d
k	s~ttj||j}|jjD ]jdkrt jd t}qjdkrʐqtfdd|D }|jdkst|j |j|j}W 5 Q R X j |_| |j qdt ksLtt |d}t|||rltj!" ntj!#  |jjD ]^jd	krj|	krj j|}W 5 Q R X j |_|  qq|j$  t%||
 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   |  krdS dS )Nr   rD   r   r`   )const_nodesr   r   mod_partition   s    z,split_const_subgraphs.<locals>.mod_partition)submod_0submod_1r<   NrE   r   rC   c                 3   s   | ]}|j  jkr|V  qd S r   )rP   rI   )r+   nr`   r   r   	<genexpr>   s      z(split_const_subgraphs.<locals>.<genexpr>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   rd   r0   rI   getattrr!   r-   r.   nextrK   r_   r=   r>   rJ   Z
erase_nodelocalsr
   r$   r/   r%   rL   rN   )r]   r^   r   rO   Zfound_const_foldingrb   splitZconst_gmZnon_const_gmZconst_mod_nameZnon_const_mod_nameZcall_const_gm_argsZroot_const_gmrg   Zin_noder@   r   r1   r   )ra   r?   r   r      s    





 



)Nr\   )rT   typingr   r   r   r   r   Ztorch.fxr   Ztorch.fx.noder   Ztorch.fx.passes.split_moduler   __all__r   r   r	   r8   rN   r
   r$   r7   rk   boolr   r   r   r   r   <module>   s    
B-  