o
    Zh                     @   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addZadd_mulZmul__EQUIVALENT_TYPESc                  C   s(   i } t D ]}|D ]}t|| |< qq| S N)r   list)Z_DICTvaluesv r   U/var/www/auris/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)Z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   Z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%   Zpartition_types_setr"   r#   Z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)r)   r%   Zinclude_functional_equivalentr*   Ztyped_partitionsr"   Ztypes_to_matchr   Ztyped_partitions_listZfusion_candidatesZ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 )NZget_attr)	args
isinstancetorchfxr	   optargetstrZget_submodule)r3   r4   r5   Zsubmod_node	submoduler   r   r   _get_submodule{   s   
r>   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).
    Zcall_function      r   )r.   nodesr:   r;   r8   opsZhigher_orderZcondappendr>   Zmap_impl)r3   control_flow_submodulesr4   r   r   r   _get_control_flow_submodules   s   

rE   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   )r+   _r=   r   r   r   r-      s    z/bfs_trace_with_node_process.<locals>.<listcomp>N)r7   r   r8   r9   GraphModuletyper3   popr.   rA   r:   rE   r!   )rF   rG   r)   queueZcurrent_graph_moduler4   rD   r   r   r   r      s$   



r   r   )TN)?r/   operatorcollectionsr   collections.abcr   typingr   r   r   r   r8   Ztorch.exportr   Ztorch.fxr	   Z*torch.fx.passes.utils.source_matcher_utilsr
   r   r   __all__nnZConv1dZ
functionalZconv1dZConv2dZconv2dZAdaptiveAvgPool2dZadaptive_avg_pool2dZReLUZreluZrelu_ZBatchNorm2dZ
batch_normZHardtanhZhardtanhZ	hardtanh_r   iaddr   imulr   r   r&   __annotations__r   r   r   r   r    r$   r(   r9   rK   boolr   inttupler<   Moduler>   rE   r   r   r   r   r   <module>   sp   




