o
    H&i/                  	   @   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 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DictOptionalSet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__ KC:\wamp64\www\opt\env\Lib\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                    sF   t jjt| ts
| n
t | gj jdt| t jr| jdS 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   r&   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$    
r	   gminline_mod_namec              	      s  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
}i  d} fdd}|jjD ]H}|jdkrQ||  |< |d7 }q?|jdkrf|j
d }	t|	|}
||
 q?| j| | j||}W d   n1 s~w   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_fnb   s   z&_inline_module.<locals>.replacement_fnplaceholder   output)dictZnamed_modulesr&   r   r   r   r   nodesoptargetr!   r   replace_all_uses_withinserting_beforeZ	node_copyeliminate_dead_code)r9   r:   Z
inline_modZcall_mod_node_to_replacer>   Zcall_mod_argsZph_countrA   Zinline_nodeZoutputsZoutput_replacementsr?   r   r@   r   _inline_moduleM   s8   





rL   
mod_tracedname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+)$NZ_1rC      )resubisdigithasattrmatchgroupr'   )rM   rN   rV   basenumr   r   r   r
   z   s   



r
   cpumoduleskip_folding_node_fnr   c              	      s  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|| |}|j|j}}d\}	}
|jjD ]jd	krt|jt|j qp|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|||r4tj ! ntj "  |jjD ]9jd	krvj|	krvj j|}W d
   n	1 sdw   Y  j |_|  n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>   rD   rB   get_attrTr>   c                    s   |  v rdS dS )Nr   rC   r   r>   )const_nodesr   r   mod_partition   s   z,split_const_subgraphs.<locals>.mod_partition)submod_0submod_1r;   NrD   r   rB   c                 3   s     | ]}|j  jkr|V  qd S r   )rN   rH   )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   rF   rG   Zall_input_nodesissubsetZ	is_impureaddr	   Noder   ra   rb   r/   rH   getattrr!   r-   nextrJ   r]   r<   r=   rI   Z
erase_nodelocalsr
   r$   r.   r%   rK   rL   )r[   r\   r   rM   Zfound_const_foldingr`   splitZconst_gmZnon_const_gmZconst_mod_nameZnon_const_mod_nameZcall_const_gm_argsZroot_const_gmre   Zin_noder?   r   r0   r   )r_   r>   r   r      s   












r   )NrZ   )rR   typingr   r   r   r   r   Ztorch.fxr   Ztorch.fx.noder   Ztorch.fx.passes.split_moduler   __all__r   r   r	   r7   rL   r
   r$   r6   ri   boolr   r   r   r   r   <module>   s(    B-