U
    9%e9                     @  s	  U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZmZmZ d dlZd dlm  mZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZmZ d dl m!Z! d	d
ddddddddddddgZ"e
d Z#ej$d ddddddZ%ej$dddd d!Z&ej$d"d#d$d%Z'ej$d&dd'd(d)Z(ej$d*d+ Z)ej$d,d- Z*ej$d"d.d/d0d1Z+ej$d"d2d3d4d5Z,ej$d"d2d3d6d7Z-ej$d8d9d/d:d;Z.ej$dd<d=dZ/ej$ddd>d?d9d@dAd9dBdCdZ0ej$d8dDdEdFdGZ1ej$dHdI Z2ej$d"d9dEdJdKZ3ej$d8d9dEdLdMZ4ej$d8d9dNdOdPZ5ej$d"d9dEdQdRZ6dSdTdUdVdWZ7ej$d"d9dEdXdYZ8ej$d"d9dEdZd[Z9ej$d"d9dEd\d]Z:ej$d"d9dEd^d_Z;ej$d"d9dEd`dZ<ej$d9dadbdZ=ej$d"dAdEdcddZ>ej$dd"d9dedfdgZ?ej$d"dhdAdidjdkZ@ej$d"dAdldmdnZAej$ddddodpdqdrdsZBej$dddodtdudvdwZCej$dddhdhdodtdxdydzZDej$dddhdhddodtd{d|d}ZEej$dd~ddZFej$ddaddZGej$dddddZHej$dddddZIej$d9daddZJej$d9daddZKej$ddddZLej$dddddZMej$d	ddddZNej$ddddZOej$dd ZPej$ddddZQej$ddddZRej$d
ddddZSej$ddddZTej$ddddZUej$ddddZVej$ddddZWej$ddddZXej$dddd9ddddZYej$dd ZZej$ddddZ[ej$ddddZ\ej$ddddZ]ej$ddddZ^ej$ddddZ_ej$ddddddZ`ej$ddddZaej$ddddZbej$ddddÄZcej$dddddńZdej$ddddǄZeej$dddd˜dd̈́Zfej$dhddpdΜddZgej$ddddфZhej$ddӄ Ziej$ddՄ Zjej$ddddׄZkej$ddd"dddڜddZlej$ddd"d"d"dod"dܜddZmej$dddddZnej$dd	 ZoepddddhdddZqepddddd Zrepdddd9dddZsejtjuejtjvejtjwejtjxejtjyejtjzejtj{ejtj|ejtj}ejtj~ejtjejtjejtjdZddddddddddddddddZejejejejejejejejejejejejejejejejgZejejejejejejejejejejejejejejejdZed ed ed ed ed ed ed ed ed ed ed ed ed ed ed ed gZe Zded< dS (      )annotationsN)
AnyCallableListLiteralNoReturnOptionalSequenceSetTupleUnion)_C)
_constants_deprecation_type_utilserrors)GLOBALS)	_beartype	jit_utils)Numberargs_have_same_dtypecast_pytorch_to_onnxcheck_training_modedequantize_helperis_caffe2_aten_fallbackis_complex_value
parse_argspytorch_name_to_typequantize_helperquantized_argsrequantize_bias_helperscalar_name_to_pytorchscalar_type_to_onnxscalar_type_to_pytorch_type)	viisffsbstnone_ValueDescriptorzOptional[str])descarg_name	node_namec              	   C  s  |dkr| S |dkst | s | S |  }| r4d S | dkrt|d}|dkrZt|S |dkrjt|S |dkrzt|S |dkrt|S |d	kr|S |d
krdd |D S |dkrdd |D S t	
d| d| d| n| dkr`|d
krL| D ]6}| }| dk rt	
d| d| d|  qdd |   D S t	
d| d| |d kst|d krt	
d|  d| t	
d| d| d|  d| d S )Nr,   r$   onnx::Constantvaluer%   r'   r)   r*   r+   r&   c                 S  s   g | ]}t |qS  )int.0r$   r3   r3   Y/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/onnx/symbolic_helper.py
<listcomp>]   s     z_parse_arg.<locals>.<listcomp>r(   c                 S  s   g | ]}t |qS r3   )floatr5   r3   r3   r7   r8   _   s     z5ONNX symbolic does not understand the Constant node 'z' specified with descriptor ''.prim::ListConstructzFailed to export a node 'z' (in list node z_) because it is not constant. Please try to make things (e.g. kernel sizes) static if possible.c                 S  s   g | ]}t t| d qS r2   )r4   	_node_getnoder5   r3   r3   r7   r8   r   s     zbONNX symbolic does not know how to unpack the ListConstruct node that is not a list of integers: ''z*Expected node type 'onnx::Constant', got 'z2Expected node type 'onnx::Constant' for argument 'z' of node 'z', got ')	_is_valuer>   
mustBeNonekindr=   r4   r9   boolstrr   SymbolicValueErrorinputs)r2   r.   r/   r0   r>   Znode_valr$   Zelement_noder3   r3   r7   
_parse_argA   sd    


rG   z_C.NoderD   )r>   keyc                 C  s(   t | tjst| |}t| ||S )z@Gets attributes of a node which is polymorphic over return type.)
isinstancer   NodeAssertionErrorZkindOfgetattr)r>   rH   selr3   r3   r7   r=      s    
r=   z_C.Valuer<   c                 C  s   |    dkS )z$Whether a Value is an ONNX constant.r1   r>   rB   r<   r3   r3   r7   _is_onnx_constant   s    rO   z9Optional[Union[_C.Value, torch.Tensor, Number, Sequence]]r2   
descriptorc                 C  s"   t | tjrt| rt| |S | S N)rI   r   ValuerO   rG   rP   r3   r3   r7   _maybe_get_const   s    
rT   c                 C  s(   t | d}t|tjr$|jdkr$|S | S )Nr+   r3   )rT   rI   torchTensorshape)r2   value_tr3   r3   r7   _maybe_get_scalar   s    
rY   c                 C  s,   t | s"td| d|  d| t| |S )Nz0ONNX symbolic expected a constant value of the 'z' argument, got 'r?   )_is_constantr   rE   rG   )r2   r.   r/   r3   r3   r7   
_get_const   s    r[   zList[_C.Value])
list_valuereturnc                 C  s4   |   }| dkr(td| d| t| S )Nr;   z;ONNX symbolic expected node type prim::ListConstruct, got 'r:   )r>   rB   r   rE   listrF   )r\   Z	list_noder3   r3   r7   _unpack_list   s    
r_   zTuple[_C.Value, ...])tuple_valuer]   c                 C  s4   |   }t| s(td|  d| t| S )Nz>ONNX symbolic expected node type 'prim::TupleConstruct', got 'r:   )r>   _is_tuple_constructr   rE   rB   tuplerF   )r`   
tuple_noder3   r3   r7   _unpack_tuple   s    rd   c                 C  s`   |   }t| s4td| d|  dtj | t| }t	|dks\t	|dks\t
|S )zUnpacks a quantized tensor into a tuple of tensor and scale/zero_point.
    Args:
        tuple_value: A tuple of tensor, scale, zero_point, and optionally axis.
    Returns:
        A tuple of tensor, scale, zero_point, and optionally axis.
    z&ONNX symbolic expected the output of `zQ` to be a quantized tensor. Is this likely due to missing support for quantized `z`. Please create an issue on       )r>   ra   r   rE   rB   r   PYTORCH_GITHUB_ISSUES_URLrb   rF   lenrK   )r`   rc   unpackedr3   r3   r7   _unpack_quantized_tensor   s    rj   r   rC   c                 C  s   t | o|   dkS )Nr;   r@   r>   rB   )r\   r3   r3   r7   _is_packed_list   s    rl   arg_descriptorsc                    s    fdd}|S )a  A decorator which converts args from torch._C.Value to built-in types.

    For example:

    ```
    @parse_args('v', 'i', 'fs')
    foo(g, a, b, c):
        assert isinstance(a, torch._C.Value)
        assert isinstance(b, int)
        assert isinstance(c, list)
        assert isinstance(c[0], float)
    ```

    Args:
        arg_descriptors: list of str, where each element is
            a string that specifies the type to convert to. Valid descriptors:
            "v": no conversion, keep torch._C.Value.
            "i": int
            "is": list of int
            "f": float
            "fs": list of float
            "b": bool
            "s": str
            "t": torch.Tensor
            "none": the variable is unused
    c                   s"    _ t  fdd}|S )Nc              	     s  d}t t |ks>tdt | dt  dj d| z*t}t|j dd  }j W n& tk
r   d gt | }d  Y nX  fddt	||D }t |dkstd	j d
| t |dkrd|kstd	j d| | f||S )NzIf you believe this is not due to custom symbolic implementation within your code or an external library, please file an issue at https://github.com/pytorch/pytorch/issues/new?template=bug-report.yml to report this bug.z,A mismatch between the number of arguments (z) and their descriptors (z") was found at symbolic function 'z'.    c                   s    g | ]\}}}t ||| qS r3   )rG   )r6   argZarg_descr/   fn_namer3   r7   r8   !  s   zBparse_args.<locals>.decorator.<locals>.wrapper.<locals>.<listcomp>zSymbolic function z4's '**kwargs' can contain a single key/value entry. _outputsz='s '**kwargs' can only contain '_outputs' key at '**kwargs'. )
rh   rK   __name__inspect	signaturer^   
parameterskeys	Exceptionzip)gargskwargsZFILE_BUG_MSGsig	arg_names)rn   fnrq   r7   wrapper
  s.    $





z.parse_args.<locals>.decorator.<locals>.wrapper)Z_arg_descriptors	functoolswrapsr   r   rm   r   r7   	decorator  s    )zparse_args.<locals>.decoratorr3   )rn   r   r3   rm   r7   r      s    /T)scale
zero_pointquantize_outputzOptional[float]zOptional[int])arg_q_descriptorsr   r   r   c                   s    fdd}|S )a  A decorator which extends support for quantized version of the base operator.

    Quantization is detected by examining the arguments that are annotated by
    `arg_q_descriptors`.

    If quantization is detected, the base operator symbolic function will be wrapped with
    argument de-quantization and output quantization.

    Otherwise, only the base symbolic function will be invoked.

    For example:

    ```
    @quantized_args(True, False)
    def foo(g, x, y):
        return x + y
    ```

    is equivalent to

    ```
    def q_foo(g, x, y):
        if is_quantized_tensor(x):
            x = dequantize(x)
            out = foo(g, x, y)
            return quantize(out)
        else:
            return foo(g, x, y)
    ```

    Args:
        arg_q_descriptors: A sequence of bool, where each element represents if the
          argument is QTensor for quantized version of this operator. It defaults
          to False for unspecified (variable length) arguments.
        scale: Quantized output scale. If None, derive from
          the first quantized input scale.
        zero_point: Quantized output zero point. If None,
          derive from the first quantized input zero point.
        quantize_output: If True, quantize the output of the base operator. Default is True
    c                   s"   t   fdd}|S )Nc                   s  d k	r| j dtd}nd }d k	r@| j dtd}nd } dt|t    }tt||}dd }t }|D ]D\}	}
t|
r|
 	 D ]}|
||	| qq||
||	|
 q|t|sڈ| f||S g }|D ]\}	}
||	|
r0t| |
\}}}}|
| |d kr |}|d kr|}qt|
r|
 	 D ]J}||	|rFt| |\}}}}|d krv|}|d kr|}|| qF|
|
 q|
|
 q| f||}|d k	std|d k	stdrt| |||S |S )NConstantrX   )Fc                 S  s   | ot |ot|S rR   )r@   ra   )rQ   rp   r3   r3   r7   _is_arg_quantized}  s    zMquantized_args.<locals>.decorator.<locals>.wrapper.<locals>._is_arg_quantizedz-Bug: Scale must be set for quantized operatorz2Bug: Zero point must be set for quantized operator)oprU   tensorrh   rb   rz   r^   rl   r>   rF   appendanyr   ZreplaceAllUsesWithrK   r   )r{   r|   r}   Z_scaleZ_zero_pointZarg_q_descriptors_extendedZdescriptor_argsr   Zis_quantizedrQ   rp   Z	arg_inputZnon_quantized_argsZdequantized_argZ	arg_scaleZarg_zero_point_output)r   r   r   r   r   r3   r7   r   j  sp     





z2quantized_args.<locals>.decorator.<locals>.wrapper)r   r   r   r   r   r   r   r   r7   r   i  s    Rz!quantized_args.<locals>.decoratorr3   )r   r   r   r   r   r3   r   r7   r   9  s    0VzOptional[Number])xr]   c                 C  s"   t | tjr| jdkr|  S dS )z,Convert a scalar tensor into a Python value.r3   N)rI   rU   rV   rW   itemr   r3   r3   r7   _scalar  s    r   c                 C  sJ   t | tjr| S tj|tjj}|tjjkrF|  }t	| | S | S )z
    Convert self into the same type of tensor, as necessary.
    We only support implicit casting for scalars, so we never
    actually need to insert an ONNX cast operator here; just
    fix up the scalar.
    )
rI   r   rS   r   JitScalarType
from_value	UNDEFINEDZscalar_namelowerrL   )selfr   scalar_typetyr3   r3   r7   _if_scalar_type_as  s     r   c                 C  s   |    S rR   )r>   rA   r   r3   r3   r7   _is_none  s    r   c                 C  s   t | tjS rR   )rI   r   rS   r   r3   r3   r7   r@     s    r@   )r2   r]   c                 C  s   t |  p|   dkS )N>   r1   prim::Constantrk   r<   r3   r3   r7   rZ     s    rZ   c                 C  s   |   tj S rR   )typeZisSubtypeOfr   
TensorTypegetr   r3   r3   r7   
_is_tensor  s    r   z
_C.JitTypezOptional[_C.ListType])jit_typer]   c                 C  s   t | tjr| S d S rR   )rI   r   ListType)r   r3   r3   r7   _as_list_type  s    r   c                 C  s   t |  d k	S rR   )r   r   r   r3   r3   r7   _is_list  s    r   c                 C  s(   t |  }|d krdS t| tjS )NF)r   r   rI   ZgetElementTyper   r   r   x_typer3   r3   r7   _is_tensor_list  s    r   c                 C  s,   t |  }|dkrdS tj| }| S )zChecks if x is a scalar list, for example: List[float], List[int].

    Besides checking the type is ListType, we also check if the data type is
    a valid ONNX data type.
    NF)r   r   r   r   r   Zonnx_compatible)r   r   r   r3   r3   r7   _is_scalar_list	  s
    r   c                 C  s   |    dkS )Nprim::TupleConstructrN   r   r3   r3   r7   ra     s    ra   c                 C  s4   t | sttj| tjjtjjtjjtjjhkS rR   )	r@   rK   r   r   r   r   Z	COMPLEX32	COMPLEX64
COMPLEX128r   r3   r3   r7   r     s     )r]   c                   C  s   t jtjjkotjS rR   )r   operator_export_type_C_onnxOperatorExportTypesZONNX_ATEN_FALLBACK_CAFFE2_ATEN_FALLBACKr3   r3   r3   r7   r   (  s    c                 C  s6   t | r|  d krd S |  }ttj|}| S rR   )r   r   typingcastr   r   dimr   r3   r3   r7   _get_tensor_rank0  s
    r   )r   allow_nonstaticc                 C  sB   t | r|  d krd S |  }ttj|}|r:| S | S rR   )r   r   r   r   r   r   ZvaryingSizessizes)r   r   r   r3   r3   r7   _get_tensor_sizes9  s    r   r4   )r   r   r]   c                 C  s   t | }|r|| S d S rR   )r   )r   r   r   r3   r3   r7   _get_tensor_dim_sizeH  s    r   )r   r   c                 C  sn   |dkr$t | }|d k	st|| S |d krjt| }|d k	s@tt|D ] \}}|d k	rH|dkrH|  S qH|S )Nre   )r   rK   r   	enumerate)r   r   Ztensor_rankr   indexsizer3   r3   r7   _get_dim_for_crossN  s    
r   zOptional[_C.Value]None)r   msgr2   r]   c                 C  sF   t jr td|  d| d n"tjt jjkrBt|  d| | d S )NONNX export failed on z	 because z not supportedz, )	r   r   warningswarnr   r   r   ZONNX_onnx_unsupported)r   r   r2   r3   r3   r7   _unimplemented^  s    r   r   )op_namer2   r]   c                 C  s8   d|  dt j }t|tjr*t||t|d S )Nz%Unsupported: ONNX export of operator zR. Please feel free to request support or submit a pull request on PyTorch GitHub: )r   rg   rI   r   rS   r   rE   OnnxExporterError)r   r2   messager3   r3   r7   r   g  s    r   )r   current_opsetsupported_opsetr2   r]   c                 C  s>   d|  d| d| d}t |tjr0t||t|d S )NUnsupported: ONNX export of 
 in opset . Please try opset version .rI   r   rS   r   rE   r   )r   r   r   r2   r   r3   r3   r7   _onnx_opset_unsupportedv  s    r   )r   r   r   reasonr2   r]   c              	   C  sD   d|  d| d| d| d	}t |tjr6t||t|d S )Nr   r   z. r   r   r   )r   r   r   r   r2   r   r3   r3   r7    _onnx_opset_unsupported_detailed  s    	r   namec                   s    fdd}|S )Nc                    s   t d  dtj dd S )Nr   z%, which is not implemented for opset z*. Try exporting with other opset versions.)r   r   r   export_onnx_opset_version)r|   r}   r   r3   r7   symbolic_fn  s    z)_block_list_in_opset.<locals>.symbolic_fnr3   )r   r   r3   r   r7   _block_list_in_opset  s    r   z#Optional[_type_utils.JitScalarType]c                  G  s4   | D ]*}t j|t jj}|t jjkr|  S qd S rR   )r   r   r   r   )r|   rp   r   r3   r3   r7   _try_get_scalar_type  s     
r   zjit_utils.GraphContext)r{   c                 C  s   t |}t|}t|s0| jdt|gd}n2|d k	rb|rb|dkrbt| || jdtdgd}tj	|tjj
}|tjjtjjhkr| jd|tjjd}| jd|||dS )	Nr   r   r   ro   CastZto_iGatheraxis_i)rY   r   r@   r   rU   
LongTensor_reshape_helperr   r   r   r   INT64INTr   TensorProtoDataType)r{   r   r   r   Zapply_reshapeZindex_constZ	index_dimZindex_scalar_typer3   r3   r7   _select_helper  s*       r   c                 C  sH   | j dkr&ddlm} || ||||S ddlm} || |||||S d S )N	   r   )_slice)opsettorch.onnx.symbolic_opset9r   Ztorch.onnx.symbolic_opset10)r{   inputaxesstartsendsZstepsZ_slice9Z_slice10r3   r3   r7   _slice_helper  s
    	
r   c                 C  s.   t j| t jjt jjt jjt jjt jjhkS rR   )r   r   r   r   FLOATDOUBLEZHALFBFLOAT16r<   r3   r3   r7   _is_fp  s     r   c                 C  s   t j| t jjt jjhkS rR   )r   r   r   r   BOOLr<   r3   r3   r7   _is_bool  s     r   c                 C  sH   t |tjrtt |tr4| jdtj|tjddS | jdt|dS )a  Creates a wrapped number based on https://github.com/pytorch/pytorch/issues/9515.

    A Tensor is a considered a "wrapped number" if it is
    auto-wrapped from a C++ or Python number type. Integer types are
    wrapped as 0-dim int64 tensors and floating-point types are
    wrapped as 0-dim double tensors.

    The input to this function is constant value. If the data type
    is a floating point type, it is converted to a 0-dim double
    tensor, else it is converted to a 0-dim tensor of its original type
    r   dtyper   )rI   rU   rV   rK   r9   r   r   double)r{   scalarr3   r3   r7   _generate_wrapped_number  s    
r   c              
   C  s   |d k	rt dd | d|}| d|| jdtj|gtjdd}| jdkrp|s\t dd	 | jd
|||ddS | jd
||||ddS d S )NZSortOut parameter is not supportedShaper   r   r   r   
   Ascending is not supportedTopK   r   outputs)r   	largest_ir  )r   r   rU   r   int64r   )r{   r   r   Z	decendingoutZshape_Z	dim_size_r3   r3   r7   _sort_helper  s(    


     r  Fc              	   C  s   |d k	rt dd t|s8| jdtj|gtjdd}nBt| || jdtdgd}t|tj	j
krz| jd|tjj
d}| jd	kr|st dd
 | jd|||ddS | jd|||||ddS d S )Nr   r   r   r   r   ro   r   r   r   r   r  r  )r   r  Zsorted_ir  )r   r@   r   rU   r   r  r   r   r   r   r   r   r   r   )r{   r   kr   largestsortedr  r3   r3   r7   _topk_helper  s(    


      r  c                 C  s>   | j dkr"ddlm} || ||S ddlm} || ||S d S )N   r   )lt)r   Ztorch.onnx.symbolic_opset8r  r   )r{   r   otherZ_lt8Z_lt9r3   r3   r7   
_lt_helper0  s
    
r  c                 C  s6   t jdkrdnd}td| d tt j d  d S )Nr   zonnx:Resizezonnx:Upsamplez(You are trying to export the model with z for ONNX opset version a  . This operator might cause results to not match the expected results by PyTorch.
ONNX's Upsample/Resize operator did not match Pytorch's Interpolation until opset 11. Attributes to determine how to transform the input were added in onnx:Resize in opset 11 to support Pytorch's behavior (like coordinate_transformation_mode and nearest_mode).
We recommend using opset 11 and above for models using this operator.)r   r   r   r   rD   )interpolate_modeZonnx_opr3   r3   r7   _interpolate_warning<  s    r  c                 C  sv   t |d rN| jdkr>| jdtj|tjdd}| d||S | jd||dS | jdk rdtd|| d||d S )	Nr      r   r   r   Z	Unsqueezeaxes_iz<Opset version must be >= 13 for Unsqueeze with dynamic axes.)rZ   r   r   rU   r   longr   rE   )r{   r   r  r   r3   r3   r7   _unsqueeze_helperN  s    

 r  c                 C  s   t |d rN| jdkr>| jdtj|tjdd}| d||S | jd||dS | jdk rdtd||d }t|}|d k	st	|d	krtd
|n$|dkrt
| |dg}| d||S | d||S )Nr   r  r   r   r   ZSqueezer  z:Opset version must be >= 13 for Squeeze with dynamic axes.ro   zCFor Squeeze axses as input, the axes rank must be one in ONNX spec.)rZ   r   r   rU   r   r  r   rE   r   rK   r  )r{   r   r  r   Zaxes_tZ	axes_rankr3   r3   r7   _squeeze_helper]  s,    

  r  ro   c                 C  sv   t |d}| jdkr`|rNt|s:| jdtj|tjdd}| jd||||dS | jd|||dS | jd|||dS d S )	Nr%   r  r   r   r   Z	ReduceSum)
keepdims_inoop_with_empty_axes_i)r  r  )rT   r   r@   r   rU   r   r  )r{   r   r  r  r  r3   r3   r7   _reducesum_helperw  s,    

 r  c                   s   t dtrd}| jdtj|tjdd}| jdtjjd}t	| | dd	gt
jg|gd
}| jd|tjjd}| d||}| jd||d	d}	n6 fddtd	 D }
| jdtj|
tjdd}	|	S )Nr&   r  r   r   r   r   r   r   r   r   r   r   DivConcatr   c                   sD   g | ]<}|d k rdn*t  |   t    |    qS )r        ?)r9   r   r   r6   r%   r   r   output_sizer3   r7   r8     s   z/_interpolate_size_to_scales.<locals>.<listcomp>)rT   r@   r   rU   onesfloat32r   r   r   r   sysmaxsizeranger   )r{   r   r!  r   offsetoffsetsZdividendZdivisorZ
scale_dimsscalesZscales_constantr3   r   r7   _interpolate_size_to_scales  s.    
 
    r*  c                 C  sv   t |d ddkot|d  }|s(d S | jdtjdtjdd}| jdtt |d dd}| jd||dd	}|S )
Nr   r(   r   r   r  r   r   r  r   )rT   r   r   rU   r"  r#  r   )r{   r)  Zavailable_scalesr(  Zscales_listr3   r3   r7   $_interpolate_get_scales_if_available  s     r+  c                 C  s@   |dkrd }|dd  }n|d }|dd  }t | |}||fS )Nnearestr   ro   )r+  )r{   moder|   align_cornersr)  r3   r3   r7   _get_interpolate_attributes  s    
r/  c                   s   | j dtjdtjdd}t }t  tjsB|d k	rT|dkrT| j d| ddS t	|  dg | j d t
jjd	  fd
dt|d D }| j d|f|ddi  S )Nr   r  r   r   r   r  r   r   r   c                   s   g | ]} qS r3   r3   r  scale_factorr3   r7   r8     s     z+_interpolate_get_scales.<locals>.<listcomp>r   )r   rU   r"  r#  r   rI   r   r   r   r  r   r   r   r&  )r{   r1  r   r(  Zscale_factor_rankr)  r3   r0  r7   _interpolate_get_scales  s"      r2  c                   s  t |d}d|krd}d|kr"d}t| t |d}t|trL|rLtddS |  sbtddS |  }t|st| ||}n|t st	 st  d d	k}|rt
|  d	g  fd
dt|d D  | jd dd	i t| | |}n
tddS ||fS )Nr*   linearcubicr)   Zinterpolatezalign_corners == Truemissing input shaper+   r   c                   s   g | ]} qS r3   r3   r  r   r3   r7   r8     s     z4_interpolate_get_scales_and_mode.<locals>.<listcomp>r  r  r   z.Both size and scales are None in __interpolate)r  )rT   r  rI   rC   r   r   r   r   r2  rl   r  r&  r   r*  )r{   r   r   r1  r-  r.  r   	is_scalarr3   r6  r7    _interpolate_get_scales_and_mode  s6    



 r8  ztorch._C.Value)r{   r   r   keepdimr   c                   s    fdd}t |rt | jdtdgd}||ddd}|r d	|} d	|}	 jd
|	tjdgtjdd}
 d||
}|S t|d}||||dS )Nc                   s0    j dkr j| ||ddS  j| ||dS )N   F)r   r  Zselect_last_index_ir   r  )r   r   )r   r   r  r{   r   r3   r7   
op_wrapper  s    
z)_argmin_argmax_helper.<locals>.op_wrapperr   r   r   r   Fr;  r   ConstantOfShapero   r   Reshaper%   )r   r   r   rU   r   r  rG   )r{   r   r   r9  r   r=  Z	flattenedr   Zinput_shapeZinput_shape_shapeZ	new_shaper3   r<  r7   _argmin_argmax_helper  s(      
r@  c                   s   t ddd fdd}|S )NTFc                   s<  t |  |\}}t|} dkr$dn
|r,dnd}|d kr| d|}t| |dgdgdgd}| jd	|tjjd
}| jd||dd}| jdkrt| }	t| }
n4| jdt	j
g t	jdd}	| jdt	j
g t	jdd}
| jd||	|
||d dd	S | jdkrt| }	n| jdt	j
g t	jdd}	| jd||	||d ddS d S )Nr,  
asymmetricr.  
half_pixelr   r   r  r  r   r   r  r   r  r   r   r   Resize      floorZ coordinate_transformation_mode_sZcubic_coeff_a_fZmode_sZnearest_mode_s)r/  rY   r   r   r   r   r   r   "_optional_input_placeholder_tensorrU   r   r#  )r{   r   r!  r|   r)  r.  coordinate_transformation_mode
input_sizeZinput_size_beg	empty_roiempty_scalesr  r3   r7   r   .  sz          

  
 z(_interpolate_helper.<locals>.symbolic_fn)r   )r   r   r  r   r3   rL  r7   _interpolate_helper,  s    
>rM  c                   s8  t |d}d|krd}d|kr"d}t |d}t|ts:dn|}|dkrJdn
|rRdnd	}t s| d
|}t| |dgdgdgd}z t  ot  d dk}	W n, tk
r   t  }	|	st	
d Y nX |	r.t|}
|
d krtddS t|  dg  fddt|
d D  | jd# ddi | jd tjjd | jd| dd | jdkrrt| }t| }n4| jdtjg tjdd}| jdtjg tjdd}| jd||| |d|dd 	S t|}
|
d krtd!d"S | jdkrt| }n| jdtjg tjdd}t| ||
}| jd||||d|dd S d S )$Nr*   r3  r4  r)   Fr,  rA  r.  rB  r   r   r  r  r+   zkCannot verify if the output_size is a scalar while exporting interpolate. Assuming that it is not a scalar.z'interpolate (with a scalar output_size)z?missing input shape (try giving an array of output_size values)c                   s   g | ]} qS r3   r3   r  r6  r3   r7   r8     s     z(__interpolate_helper.<locals>.<listcomp>r  r   r   r   r   r  r   r   r   rC  rD  rE  rF  zinterpolate (with scales)r5  )r  )rT   rI   rC   r   r   r   rl   r   AttributeErrorr   r   r   r   r  r&  r   r   r   r   rG  rU   r   r#  r2  )r{   r   r   r1  r-  r.  Zrecompute_scale_factorrH  rI  r7  rankrJ  rK  r)  r3   r6  r7   __interpolate_helperp  s    







 


rP  c                 C  sJ   | j dk rddlm} n$| j dkr0ddlm} nddlm} || |||S )N   r   )unbindr:  )r   r   rR  torch.onnx.symbolic_opset11torch.onnx.symbolic_opset13)r{   r   r   rs   rR  r3   r3   r7   _unbind_helper  s    

rU  c                 C  s4   | j dkrddlm} nddlm} || ||||S )Nr   r   scatter)r   r   rW  rS  )r{   r   r   r   srcrW  r3   r3   r7   _scatter_helper  s    
rY  c                 C  sp   | j dkr&| jd|dg| ||d}n8ddlm} | jdtdg| d}|| ||||d	}|dkrj|S |gS )
Nr:  ZSplitro   )Zsplit_ir   r  r   )splitr   r   )rs   )r   r   rT  rZ  rU   r   )r{   r   repsr   Z	split_outrZ  repeatsr3   r3   r7   _repeat_interleave_split_helper  s    
r]  c                 C  s,  ddl m}m} t|s,| jdt|d}t|}t|d}t	|dkrj| d|| jdt
dgd}|| ||d }|rtjt	|tjd}	||	|d < | jd|	d}
n^| d	|| |d d| jdt
t	|d| jd
| jdt
dgd|dd}	|| |	dd}
| d||
}|| |||d S )Nr   )flatten	unsqueezer   r   r+   r?  ro   r   ZOneHotr  r   ZTile)r   r^  r_  r   r   rU   r   rZ   rT   r   r   r"  r  )r{   r   r\  r   r^  r_  Zconst_repeatsr[  Z
unsqueezedZonehotZrepeats_per_dimZtiledr3   r3   r7   -_repeat_interleave_single_value_repeat_helper  s:    
     
r`  z\Tuple[_type_utils.JitScalarType, Optional[_C.Value], Optional[_C.Value], Optional[_C.Value]])r{   r]   c                 C  s   dd }|d ks t |rJt|rJ||||gr8tjj}qbtjt }nt|t	sXt
t|}|rz| jd|| dnd }|r| jd|| dnd }|r| jd|| dnd }||||fS )Nc                 S  s>   | D ]4}t j|t jj}|t jjkr|t jjkr dS qdS )NFT)r   r   r   r   r   )Zscalarsr   r   r3   r3   r7   _is_all_integral)  s     

z-_arange_cast_helper.<locals>._is_all_integralr   r   )r@   r   r   r   r   Z
from_dtyperU   Zget_default_dtyperI   r4   rK   r   	onnx_type)r{   endstartstepr   ra  r   r3   r3   r7   _arange_cast_helper   s    	

rf  c                 G  s2   | j dkrddlm} nddlm} || f| S )Nr   r   )arange)r   r   rg  rS  )r{   r|   rg  r3   r3   r7   _arange_helperK  s    
rh  c                 C  s8   |  d|}ddlm} || || j dtdgd|S )Nr   r   )selectr   r   )r   r   ri  rU   r   )r{   r   r   Z
full_shaperi  r3   r3   r7   _size_helperT  s    rj  c           
   	     s   ddl m} | jdkr$ddl m} nddlm} |  d krJtddS |  }t|d t	| | fdd	t
|D }|| | d
|dt	| |dg| d
|}|| ||d }	||	fS )Nr   )expandr   rV  Z
index_fillzinput rank not accessibler%   c                   s   g | ]}| kr|qS r3   r3   r  Z	dim_valuer3   r7   r8   p  s      z._index_fill_reshape_helper.<locals>.<listcomp>r   )r   rk  r   rW  rS  r   r   r   rG   r  r&  r   )
r{   r   r   r   rk  rW  Zself_dimZunsqueezed_indexZexpanded_index_shapeZexpanded_indexr3   rl  r7   _index_fill_reshape_helper\  s,    


   
   
rm  c                 C  sl   t |d}t|s&| jdt|d}| jdkrV|dkrHtdtjd| | d||S | jd|||d	S d S )
Nr&   r   r   r  ro   zReshape with allowzero=1   r?  )Zallowzero_i)	rT   r@   r   rU   r   r   r   r   r   )r{   r   rW   Z	allowzeror3   r3   r7   r   ~  s    

   r   c              	   C  sr  ddl m} t|d}t|d}|d ks0t|rr|d krDtd|tjdg| tj	
| d}	| jd|	d}|d kst|r|d krtd|tjd	g| tj	
| d}
| jd|
d}|d kst|s|d kst|rf|d k	r|d k	stt| || jdtj||d
gtjdd}| jd|dddgd}|| || jdtjddgtjdddd\}}||||fS )Nr   )	_var_meanro   z@Unsupported: ONNX export of batch_norm for unknown channel size.r  r   r   r   g        r   Z	Transposer  )Zperm_iF)r   ro  r   r   r   rE   rU   r   r   r   r   r   r   rK   r   r  )r{   r   weightbiasZrunning_meanZrunning_varro  Z
batch_sizeZchannel_sizeZweight_valueZ
bias_valueZ
reshape_inZtrans_inr3   r3   r7   _batchnorm_helper  sf    

rr  zCallable[[Any], Sequence[int]]zUnion[int, Sequence[int]]zTuple[int, ...])tuple_fnpaddingr]   c                 C  s*   |r|   dkrt|d t| |S )Nr   divisor_override)r>   rB   r   rb   )rs  rt  Zkernel_sizeZstrideru  r   r3   r3   r7   _avgpool_helper  s    	
rv  )op_train_moder   r]   c                 C  sn   t jtjjkrdS | r tjj}ntjj}|t jkr6dS dt|  }t	dt j d| d| d| d	 dS )zMWarns the user if the model's training mode and the export mode do not agree.Nztrain=zONNX export mode is set to z, but operator 'z' is set to z. Exporting with r   )
r   Ztraining_moder   ZTrainingModeZPRESERVEZTRAININGZEVALrC   r   r   )rw  r   Zop_mode_enumZop_mode_textr3   r3   r7   r     s    

c                 C  s   |  d|}t| |dgdg|gd}|| j dtjdgtjddg}||d k rt| |dg|d g|gd}|| j dtjdgtjdd|g}| j d|d
di}	ddlm}
 |
| ||	S )Nr   r   )r   r   r   r   r   r   r   ro   r  r   )_reshape_from_tensor)r  )r   r   rU   r   r  r   rx  )r{   r   Z	start_dimZend_dimr   rI  Zslice1ZslicesZslice3Zfinal_shaperx  r3   r3   r7   _flatten_helper  s$         ry  c                 C  s,   |d krdS t | r(|   dkr(dS dS )NFr1   Trk   )Zsplit_size_or_sizesrs   r3   r3   r7   _is_split_static  s    rz  c                 C  s   |  d}|tj  |S )Nr   )r   ZsetTyper   ZOptionalTypeZofTensor)r{   nr3   r3   r7   rG    s    
rG  c                   sJ   t  }|d k	r:t fddt|D r:| j| ddS | j| ddS )Nc                 3  s   | ]}t  |d kV  qdS )r   N)r   r  r   r3   r7   	<genexpr>  s    z*_handle_reduce_dim_none.<locals>.<genexpr>ro   )r  r   )r   r   r&  r   )r{   r   r   rO  r3   r|  r7   _handle_reduce_dim_none  s    r~  z%Optional[_C_onnx.TensorProtoDataType]z7Tuple[_C.Value, _C.Value, _C.Value, Optional[_C.Value]])r{   qtensorqdtyper]   c                 C  s   t |}|dd \}}}t|dkr.|d nd}t|dd}tj|}	|dkrl|	dk	rd|	 }ntjj	}| j
d||d}
| j
d|tjjd}| j
d||d}|dk	rtjdk rtd	tjdd
| | j
d	|
|||d|||fS )a  Appends to graph `g` ONNX nodes that dequantizes `qtensor` into `tensor`.

    Args:
        g: Graph, the ONNX IR graph that is under construction.
        qtensor: torch._C.Value, either a tuple of (quantized_tensor, scale, zero_point)
            for per tensor quantization, or
            (quantized_tensor, scale, zero_point, axis) for per channel quantization,
            representing the quantized tensor.
        qdtype: torch.onnx.TensorProtoDataType default None, if not None, represents the
            data type of quantized tensor. It must be either
            torch.onnx.TensorProtoDataType.UINT8 or torch.onnx.TensorProtoDataType.INT8.
    Nre   rf   r%   axisr   r   r  ZDequantizeLinear Attribute axis is not supported.r   )rj   rh   r[   r   r   r   rb  r   r   UINT8r   r   r   r   r   )r{   r  r  Zunpacked_qtensorsr   r   r   r  r   Zinput_qdtyper2   r3   r3   r7   r   #  s2    
	)r{   r   r   r   r  r]   c              	   C  s   |dk	r,t |s,tjdk r,tdtjdd| |dk	s8ttj|tjjtjj	krf| j
d|tjj	d}|dk	srttj|tjjtjjtjjhkr| j
d|tjjd}| j
d|||t|ddd	}|||g}|dk	rt |s|| | j
d| S )ai  Appends to graph `g` ONNX nodes that quantizes `tensor` based on `scale`, `zero_point` and `axis`.

    Args:
        g: Graph, the ONNX IR graph that is under construction.
        tensor: torch._C.Value, representing the tensor to be quantized.
        scale: torch._C.Value, quantized scale.
        zero_point: torch._C.Value, quantized zero point.
        axis: Optional[torch._C.Value] default None, if None, represents per tensor quantization.
            Otherwise, represents per channel quantization, along given axis.

    Returns:
        A TupleConstruct storing information of the quantized tensor.
    Nr  ZQuantizeLinearr  r   r   r%   r  r   r   )r   )r   r   r   r   rK   r   r   r   r   r   r   r   r   r  INT8r[   r   )r{   r   r   r   r  r   r|   r3   r3   r7   r   T  sP     


c           
      C  s   |  d||}|  d|}| j d|tjdgtjdd}| j d|  d||tjjd	}g }	|d
k	rtt|st|	| | j d|||f|	 S )ad  In PyTorch, bias is float and is quantized to int32 implicitly inside the quantized ATen op kernel.
    In ONNX we need to make the quantization explicit because operators expect all of their inputs to be quantized.
    Since int32 is not a supported output type by ONNX operator `QuantizeLinear`, quantization is exported using
    regular operators.
    ZMulr   r>  r   r   r   r   r  r   Nr   )	r   rU   r   r4   r   r   INT32r   r   )
r{   rq  Zinput_scaleZweight_scaler  Z
bias_scaleZbias_scale_shapeZbias_zero_pointZq_biasZ	axis_argsr3   r3   r7   r      s     	    
c                   s2   | st tj| d  t fdd| D }|S )Nr   c                 3  s   | ]}t j| kV  qd S rR   )r   r   r   )r6   elemZ
base_dtyper3   r7   r}    s    z'args_have_same_dtype.<locals>.<genexpr>)rK   r   r   r   all)r|   Zhas_same_dtyper3   r  r7   r     s    z1.13z2.0z>remove its usage and avoid setting internal variables directlyZopset_versionc                 C  s
   | t _d S rR   )r   r   r  r3   r3   r7   _set_opset_version  s    r  c                 C  s
   | t _d S rR   )r   r   )r   r3   r3   r7   _set_operator_export_type  s    r  onnx_shape_inferencec                 C  s
   | t _d S rR   )r   r  r  r3   r3   r7   _set_onnx_shape_inference  s    r  )ByteCharDoubleFloatHalfIntLongShortBoolComplexFloatComplexDoubleBFloat16	Undefinedr  r  r  r  r  r  r  r  r  r  r  QInt8QUInt8QInt32r  )Zuint8_tZint8_tr   r9   halfr4   Zint64_tZint16_trC   	complex64
complex128qint8quint8qint32bfloat16)r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  zSet[int]_quantized_ops)NN)T)N)N)N)N)T)N)TN)TFN)Nro   r   )NNN)r   )N)N)N)
__future__r   r   ru   r$  r   r   r   r   r   r   r   r   r	   r
   r   r   rU   Ztorch._C._onnxr   Z_onnxr   Z
torch.onnxr   r   r   r   Ztorch.onnx._globalsr   Ztorch.onnx._internalr   r   Ztorch.typesr   __all__r-   ZbeartyperG   r=   rO   rT   rY   r[   r_   rd   rj   rl   r   r   r   r   r   r@   rZ   r   r   r   r   r   ra   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r*  r+  r/  r2  r8  r@  rM  rP  rU  rY  r]  r`  rf  rh  rj  rm  r   rr  rv  r   ry  rz  rG  r~  r   r   r    r   
deprecatedr  r  r  r   r  r  r   r   ZFLOAT16r  r   ZINT16r   r   r   r   r   r   r!   Zuint8Zint8shortr4   r  r  r9   r   Z	complex32r  r  rC   r  r  r  r  r#   r   r"   setr  __annotations__r3   r3   r3   r7   <module>   sZ   0 E


N 	

    
  #&
Cc
	*    *!9

0=


