o
    Ih                     @   s0  U d dl Z d dlZd dlmZ d dlmZ d dlmZmZm	Z	m
Z
 d dlZd dlmZ d dlmZ d dlmZmZmZ g dZejjejjjhejjejjjhejjejjjhejjejjjejjjhejj ejjj!hejj"ejjj#ejjj$hej%ej%ej&d	d
hej'ej'ej(ddhga)e*e+ e,d< dd Z-e- a.de*e+ fddZ/d-ddZ0dee fddZ1dd Z2de*e fddZ3		d.dej4j5de*e de	eege6f  fd d!Z7d"ej4j5d#ej4jd$e8de9e:ejj;ej4jf fd%d&Z<d"ej4j5de*e9e:ejj;ej4jf  fd'd(Z=d)e
eej4j5f d*eddfd+d,Z>dS )/    N)OrderedDict)Sequence)AnyCallableOptionalUnion)ExportedProgram)Node)check_subgraphs_connectedget_source_partitionsSourcePartition)find_sequential_partitionsget_equivalent_typesupdate_equivalent_types_dictbfs_trace_with_node_processaddadd_mulmul__EQUIVALENT_TYPESc                  C   s(   i } t D ]}|D ]}t|| |< qq| S N)r   list)_DICTvaluesv r   Z/var/www/vscode/kcb/lib/python3.10/site-packages/torch/ao/quantization/pt2e/graph_utils.py_create_equivalent_types_dict%   s   r   returnc                   C   s   t S r   )r   r   r   r   r   r   0   s   r   c                 C   s   | du rt d| at adS )zHelp function for user who wants to customize the _EQUIVALENT_TYPES and _EQUIVALENT_TYPES_DICT.
    When customized_equivalent_types passes in,
    re-generate _EQUIVALENT_TYPES and _EQUIVALENT_TYPES_DICT.
    Nz.customized_equivalent_types should not be None)
ValueErrorr   r   _EQUIVALENT_TYPES_DICT)customized_equivalent_typesr   r   r   r   4   s   
r   
partitionsc                 C   s.   d }| D ]}|d urt ||s dS |}qdS )NFT)r
   )r"   prev_partition	partitionr   r   r   _partitions_sequentialA   s   
r%   c                 C   s    | g}| t v r|t |   |S r   )r    extend)partition_typematching_typesr   r   r   _get_matching_typesL   s   r)   partition_typesc                 C   sB   t  }| D ]}t|}t |}t||@ dkr dS ||O }qdS )Nr   FT)setr)   len)r*   partition_types_setr'   r(   matching_types_setr   r   r   _valid_type_sequenceS   s   
r/   Tgm	filter_fnc                 C   s~   t |std| dt }|D ]}t|}t| j||}ttj	|
 ||< qt|
 }tj| }	dd |	D }
|
S )NzInvalid partition types: z*. Each type in the sequence must be uniquec                 S   s   g | ]}t |r|qS r   )r%   ).0	candidater   r   r   
<listcomp>s   s    z.find_sequential_partitions.<locals>.<listcomp>)r/   r   r   r)   r   graphr   	itertoolschainfrom_iterabler   product)r0   r*   include_functional_equivalentr1   typed_partitionsr'   types_to_matchr"   typed_partitions_listfusion_candidatesfused_partitionsr   r   r   r   ^   s"   


r   graph_modulenode	arg_indexc                 C   sR   |j | }t|tjjsJ |jdksJ t|jtsJ | |j}|j||fS )Nget_attr)	args
isinstancetorchfxr	   optargetstrget_submodule)r@   rA   rB   submod_node	submoduler   r   r   _get_submodule{   s   
rN   c                 C   sx   g }| j jD ]3}|jdkrq|jtjjju r(|t	| |d |t	| |d |jtjjj
u r9|t	| |d q|S )a{  
    Returns a list of submodules used for control flow operations
    (torch.ops.higher_order.cond/map) that are in the given toplevel graph (does not look
    into submodules). Specifically, the returned value is a list containing a
    tuple of (name of the submodule that's stored in the graph module, the
    submodule itself, and the fx node that uses this submodule).
    call_function      r   )r5   nodesrH   rI   rF   opshigher_ordercondappendrN   map_impl)r@   control_flow_submodulesrA   r   r   r   _get_control_flow_submodules   s   

rY   modelnode_opc                 C   s   t | ttjjfsJ dt|  t | tr| jn| }|g}|rI|d}|jj	D ]}|j
dv r2q*|| q*dd t|D }|| |s!dS dS )z9Traverse the graph module and apply node_op to each node.z-Expected GraphModule or ExportedProgram, got r   )outputplaceholderc                 S   s   g | ]\}}}|qS r   r   )r2   _rM   r   r   r   r4      s    z/bfs_trace_with_node_process.<locals>.<listcomp>N)rE   r   rF   rG   GraphModuletyper@   popr5   rR   rH   rY   r&   )rZ   r[   r0   queuecurrent_graph_modulerA   rX   r   r   r   r      s$   



r   r   )TN)?r6   operatorcollectionsr   collections.abcr   typingr   r   r   r   rF   torch.exportr   torch.fxr	   *torch.fx.passes.utils.source_matcher_utilsr
   r   r   __all__nnConv1d
functionalconv1dConv2dconv2dAdaptiveAvgPool2dadaptive_avg_pool2dReLUrelurelu_BatchNorm2d
batch_normHardtanhhardtanh	hardtanh_r   iaddr   imulr   r   r+   __annotations__r   r    r   r   r%   r)   r/   rG   r_   boolr   inttuplerJ   ModulerN   rY   r   r   r   r   r   <module>   sp   




