U
    ©Ê¹jm.  ã                   @   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__© ú_/var/www/html/bwave/python/venv/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|s t||jƒS tjjdœ‡ fdd„}t|| |ƒ}|j|j }}d\}	}
|jjD ]$‰ˆjd	kràt|ˆ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�rºt ˆjd tƒ}�q–ˆjdk�rÊ�q–t‡fdd„|D ƒƒ}|jdk�sðt‚|j ˆ¡� |j |j¡}W 5 Q R X ˆj ¡ |_ˆ |¡ |j ˆ¡ �q–d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>   rC   rE   Ú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-  ýü