o
    ei                     @   s   d dl Z d dlmZ d dlmZmZ d dlZd dlZd dlmZ d dlm	Z	m
Z
 d dlmZmZmZmZ d dlmZmZmZ ddlmZ G d	d
 d
e
ZG dd deZdS )    N)Callable)AnyOptional)ProxyTransformer)Argumentmap_aggregateNodeTarget)create_type_hintnormalize_functionnormalize_module   )AnnotateTypesWithSchemac                       s   e Zd ZdZ	ddejjdef fddZde	de
f fd	d
Z		ddedeedf deee
f deee
df  deeee
f  f
 fddZdedeedf deee
f f fddZ  ZS )NormalizeArgsa  
    Normalize arguments to Python targets. This means that
    `args/kwargs` will be matched up to the module/functional's
    signature and rewritten to exclusively kwargs in positional order
    if `normalize_to_only_use_kwargs` is true. Also populates default
    values. Does not support positional-only parameters or varargs
    parameters (*args, **kwargs).

    If the nodes have 'type' metadata, it will use it to disambiguate
    overloads. Otherwise, it will throw an error.

    Example usage:
        m = torchvision.models.resnet18()
        traced = torch.fx.symbolic_trace(m)
        traced = NormalizeArgs(traced).transform()
    Tmodulenormalize_to_only_use_kwargsc                    s   t  | i | _|| _d S N)super__init__node_mapr   )selfr   r   	__class__ i/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/fx/experimental/normalize.pyr   &   s   
zNormalizeArgs.__init__nreturnc                    s   |  \}}fdd tj }t|ts!tdt| tdd |D } fdd| D }jdkrE| 	j
||||}nt }jd	kr_| j|< j|j_j|j_|S )
Nc                    s    t | tjr jdS t| S )Ntype)
isinstancefxr	   metagetr   )arg)r   r   r   get_type0   s   z(NormalizeArgs.run_node.<locals>.get_typezExpected tuple, got c                 s   s    | ]}t |V  qd S r   )r   ).0ir   r   r   	<genexpr>8   s    z)NormalizeArgs.run_node.<locals>.<genexpr>c                    s   i | ]	\}}| |qS r   r   )r%   kv)r$   r   r   
<dictcomp>9   s    z*NormalizeArgs.run_node.<locals>.<dictcomp>call_functionoutput)fetch_args_kwargs_from_envr   argsr   tupleAssertionErrorr   itemsopr+   targetr   run_noder   r!   node)r   r   r.   kwargs	arg_typeskwarg_typesoutr   )r$   r   r   r4   -   s   





zNormalizeArgs.run_nodeNr3   r.   .r6   r7   r8   c           	         s\   t |stdt| t|||||| j}|r&|\}}| jd|||S t |||S )NExpected callable target, got r+   )	callabler0   r   r   r   tracercreate_proxyr   r+   )	r   r3   r.   r6   r7   r8   new_args_and_kwargsnew_args
new_kwargsr   r   r   r+   D   s    zNormalizeArgs.call_functionc                    s\   t |tstdt| t| j|||| j}|r&|\}}t |||S t |||S )NzExpected str target, got )	r   strr0   r   r   r   r   r   call_module)r   r3   r.   r6   r>   r?   r@   r   r   r   rB   ^   s   
zNormalizeArgs.call_module)T)NN)__name__
__module____qualname____doc__torchr    GraphModuleboolr   r	   r   r4   r
   r/   r   dictrA   r   r+   rB   __classcell__r   r   r   r   r      s:    



r   c                       s   e Zd ZU dZejejejejejejej	ej
ejejejejejejejejejejejejejejejejiZeeeegef eeegef f ed< dedeedf deeef f fddZ  ZS )	NormalizeOperatorsa  
    Normalize callsites that are different ways of "spelling" the same
    invocation into a single, canonical call. Currently supports:

    1. Normalize operators (e.g. operator.add) to the `torch` ops they
       ultimately invoke (e.g. torch.add) when it is possible to statically
       reason that

    Example usage:

        m = torchvision.models.resnet18()

        traced = torch.fx.symbolic_trace(m)

        traced = NormalizeOperators(traced).transform()
    binary_magic_method_remapr3   r.   .r6   c                    st   t |stdt| || jv r2t|dkr t |||S |\}}t j| j| ||fi dS t |||S )Nr:      )r3   r.   r6   )r;   r0   r   rM   lenr   r+   )r   r3   r.   r6   lhsrhsr   r   r   r+      s   
z NormalizeOperators.call_function) rC   rD   rE   rF   rG   addoperatormulsubdivtruedivfloor_dividefloordiv	remaindermodeqneltlegtgerM   rJ   r   r   __annotations__r
   r/   r   rA   r+   rK   r   r   r   r   rL   q   s2   
 

rL   )rS   collections.abcr   typingr   r   rG   torch.fxr    r   r   torch.fx.noder   r   r	   r
   torch.fx.operator_schemasr   r   r   schema_type_annotationr   r   rL   r   r   r   r   <module>   s   ]