a
    8Sic                     @  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 d dlZd dlm  mZ d dlZd dlmZ d dlmZ d dlmZ dddZd	d
 Zdd Zdd ZdddddZdd Zdd Zdd Z ddddddddd Z!d!d" Z"d#d$d%d&Z#d'd( Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(d1d2 Z)d3d4 Z*d5d6 Z+d7d8 Z,dd:d;Z-d<d= Z.d>d? Z/d@dA Z0dBdC Z1dDdE Z2dFdG Z3dHdI Z4dJdK Z5ddLdMZ6ddOdPZ7dQdR Z8dSdT Z9ddUdVZ:ddWdXZ;dYdZ Z<d[d\ Z=d]d^ Z>d_d` Z?ddbdcZ@ddde ZAdfdg ZBdhdi ZCdjdk ZDdldm ZEdndo ZFdpdq ZGdrds ZHdtdu ZIdvdw ZJddxdyZKdzd{ ZLd|d} ZMd~d ZNdddZOdd ZPddddddZQdd ZRdd ZSdd ZTdd ZUdd ZVdddddddZWdddddddddZXdddZYdd ZZddddZ[dd Z\dd Z]ddddZ^ej_j`ej_jaej_jbej_jcej_jdej_jeej_jfej_jgej_jhej_jiej_jjej_jkej_jldZmddddddddddddddddZnG dd dejoZpejqejrejsejtejuejvejwejxejyejzej{ej|ej}ej~ejejgZejqejrejxejwejvejtejuejsej|ejzej{ej}ej~ejejdZdd Zemd emd emd emd emd emd emd emd emd emd emd emd emd emd emd emd gZe Zded< dS )    )annotationsN)AnyCallableListOptionalSequenceSetTupleUnion)_C)_patch_torch)GLOBALSc                 C  s  |dkr| S |dkst | s | S |   r0d S |   dkr|  d }|dkr\t|S |dkrlt|S |dkr|t|S |dkrt|S |d	kr|S |d
krdd |D S |dkrdd |D S tdnx|   dkrF|d
kr>|  	 D ]0}|  dk rtd|   d  qdd |  	 D S td|d u sZ|d u rrtd
|   ntd
|||   d S )Nnonevonnx::Constantvalueifbstisc                 S  s   g | ]}t |qS  )int.0r   r   r   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/onnx/symbolic_helper.py
<listcomp>X       z_parse_arg.<locals>.<listcomp>fsc                 S  s   g | ]}t |qS r   )floatr   r   r   r   r   Z   r   z5ONNX symbolic doesn't know to interpret Constant nodeprim::ListConstructz$Failed to export an ONNX attribute 'z\', since it's not constant, please try to make things (e.g., kernel size) static if possiblec                 S  s   g | ]}t | d  qS r   )r   noder   r   r   r   r   g   r   z:ONNX symbolic doesn't know to interpret ListConstruct nodez.Expected node type 'onnx::Constant', got '{}'.zMExpected node type 'onnx::Constant' for argument '{}' of node '{}', got '{}'.)	_is_valuer#   
mustBeNonekindr   r    boolstrRuntimeErrorinputsformat)r   descarg_name	node_nameZtvalr   r   r   r   
_parse_argD   s^    


r/   c                 C  s&   t | r"|   dkr"t| |S | S )Nr   )r$   r#   r&   r/   )r   r,   r   r   r   _maybe_get_constz   s    
r0   c                 C  s(   t | d}t|tjr$|jdkr$|S | S )Nr   r   )r0   
isinstancetorchTensorshape)r   value_tr   r   r   _maybe_get_scalar   s    
r6   c                 C  s"   t | std|| t| |S )NzDONNX symbolic expected a constant value of the {} argument, got `{}`)_is_constantr)   r+   r/   )r   r,   r-   r   r   r   
_get_const   s    r8   z_C.ValuezList[_C.Value])
list_valuereturnc                 C  s$   |   }| dksJ t| S Nr!   )r#   r&   listr*   )r9   Z	list_noder   r   r   _unpack_list   s    r=   c                 C  s.   |   }| dkr"td|t| S )Nprim::TupleConstructzAONNX symbolic expected node type `prim::TupleConstruct`, got `{}`)r#   r&   r)   r+   r<   r*   )tuple_valueZ
tuple_noder   r   r   _unpack_tuple   s    r@   c                 C  s   t | o|   dkS r;   r$   r#   r&   )r9   r   r   r   _is_packed_list   s    rB   c                    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
    c                   s"    _ t  fdd}|S )Nc              	     s
  d}t t |ks>J dt | dt  dj d| z*t}t|j dd  }j W n$ ty   d gt | }d  Y n0  fddt||D }t |dksJ d	j d
| t |dkrd|v sJ d	j d| | g|R i |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 r   )r/   )r   argZarg_descr-   fn_namer   r   r      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'. )	len__name__inspect	signaturer<   
parameterskeys	Exceptionzip)gargskwargsZFILE_BUG_MSGsig	arg_names)arg_descriptorsfnrE   r   wrapper   sB    







z.parse_args.<locals>.decorator.<locals>.wrapper)Z_arg_descriptors	functoolswrapsrV   rW   rU   rV   r   	decorator   s    %zparse_args.<locals>.decoratorr   )rU   r]   r   r[   r   
parse_args   s    +r^   )scale
zero_pointr'   zOptional[float]zOptional[int]arg_q_descriptorsr_   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.
    c                   s(    _  _t  fdd}|S )Nc                   s  j }|d ur"| jdt|d}j}|d urD| jdt|d} dt|t    }tt||}tdd |D s| g|R i |S g }|D ]L\}}	|rt	| |	\}
}}}|
|
 |d u r|}|d u r|}q|
|	 q| g|R i |}t| |||S )NConstantr5   )Fc                 s  s&   | ]\}}|o|   d kV  qdS )r>   N)r#   r&   )r   
descriptorrD   r   r   r   	<genexpr>0  s   zEquantized_args.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>)_scaleopr2   tensor_zero_pointrH   tuplerO   anydequantize_helperappendquantize_helper)rP   rQ   rR   rg   rj   Zarg_q_descriptors_extendedZdescriptor_argsZdequantized_argsre   rD   Zdequantized_argr_   r`   _output)rb   rV   r   r   rW   !  s4    
z2quantized_args.<locals>.decorator.<locals>.wrapper)rg   rj   rX   rY   rZ   ra   r\   r   r]     s
    %z!quantized_args.<locals>.decoratorr   )r_   r`   rb   r]   r   ra   r   quantized_args   s    ,,rr   c                 C  s   |   dksJ |  S )z,Convert a scalar tensor into a Python value.rC   )numelitemxr   r   r   _scalarL  s    rw   z_C.Graph)rP   c                 C  s8   t |tjr|S |  }|r4| }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.
    )r1   r   Valuetype
scalarTypelowergetattr)rP   selfri   scalar_typetyr   r   r   _if_scalar_type_asR  s    r   c                 C  s   |    S N)r#   r%   ru   r   r   r   _is_noned  s    r   c                 C  s   t | tjS r   )r1   r   rx   ru   r   r   r   r$   h  s    r$   c                 C  s   t |  p|   dv S )N)r   prim::ConstantrA   r"   r   r   r   r7   l  s    r7   c                 C  s   |   tj S r   )ry   isSubtypeOfr   
TensorTypegetru   r   r   r   
_is_tensors  s    r   c                 C  s   t |  tjS r   )r1   ry   r   ListTyperu   r   r   r   _is_listw  s    r   c                 C  s   t | ot|   tjS r   )r   r1   ry   getElementTyper   r   ru   r   r   r   _is_tensor_list{  s    r   c                 C  s4   t |   }t| o2|t v o2t| t v 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.
    )r(   ry   r   r   scalar_name_to_pytorchrM   cast_pytorch_to_onnx)rv   element_typer   r   r   _is_scalar_list  s    
r   c                   C  s   t jtjjkotjS r   )r   operator_export_type_C_onnxOperatorExportTypesONNX_ATEN_FALLBACK_CAFFE2_ATEN_FALLBACKr   r   r   r   is_caffe2_aten_fallback  s    r   c                 C  s$   t | r|  d u rd S |   S r   )r   ry   dimru   r   r   r   _get_tensor_rank  s    r   Tc                 C  s4   t | r|  d u rd S |r(|   S |   S r   )r   ry   varyingSizessizes)rv   Zallow_nonstaticr   r   r   _get_tensor_sizes  s
    r   c                 C  s*   zt | }|| W S  ty$   Y n0 d S r   )r   rN   )rv   r   r   r   r   r   _get_tensor_dim_size  s    
r   c                 C  sR   |dkr|t |  S |d u rNt| }t|D ] \}}|d ur,|dkr,|  S q,|S )N   )r   r   	enumerate)inputr   r   indexsizer   r   r   _get_dim_for_cross  s    
r   c                 C  sF   t jr"td|  d | d  n tjt jjkrBt|  d|  d S )NzONNX export failed on z	 because z not supportedz, )	r   r   warningswarnr   r   r   ONNX_onnx_unsupported)rh   msgr   r   r   _unimplemented  s    r   c                 C  s   t d| d S )NzxUnsupported: ONNX export of operator {}. Please feel free to request support or submit a pull request on PyTorch GitHub.r)   r+   )op_namer   r   r   r     s
    r   c                 C  s   t d| ||d S )NzHUnsupported: ONNX export of {} in opset {}. Please try opset version {}.r   )r   current_opsetsupported_opsetr   r   r   _onnx_opset_unsupported  s
    r   c                 C  s   t d| |||d S )NzLUnsupported: ONNX export of {} in opset {}. {}. Please try opset version {}.r   )r   r   r   reasonr   r   r    _onnx_opset_unsupported_detailed  s
    r   c                   s    fdd}|S )Nc                    s   t d tjd S )NziONNX export failed on {}, which is not implemented for opset {}. Try exporting with other opset versions.)r)   r+   r   export_onnx_opset_version)rQ   rR   namer   r   symbolic_fn  s
    z)_block_list_in_opset.<locals>.symbolic_fnr   )r   r   r   r   r   _block_list_in_opset  s    r   c               	   G  s4   | D ]*}z|   W   S  ty,   Y q0 qd S r   )ry   rz   r)   )rQ   rD   r   r   r   _try_get_scalar_type  s    r   c                 C  s   t |}t|}t|s0| jdt|gd}n2|d urb|rb|dkrbt| || jdtdgd}|  }|d u s~|dvr| jd|t	d d}| jd	|||d
S )Nrc   rd   r   rC   )LongIntCastr   to_iGatheraxis_i)
r6   r   r$   rh   r2   
LongTensor_reshape_helperry   rz   r   )rP   r}   r   r   Zapply_reshapeZindex_constZ	index_dimZindex_scalar_typer   r   r   _select_helper  s    r   Fc           	      C  sJ   t jdkr&ddlm} || ||||S ddlm} || ||||||S d S )N	   r   )_slice)r   r   torch.onnx.symbolic_opset9r   Ztorch.onnx.symbolic_opset10)	rP   r   axesstartsendsstepsdynamic_sliceZ_slice9Z_slice10r   r   r   _slice_helper  s
    
r   c                 C  sT   | rPt | tjr*| jtjtjtjtjfv S |  	 }|d u rHt
d |dv S dS )NzWType cannot be inferred, which might cause exported graph to produce incorrect results.)FloatDoubleHalfBFloat16F)r1   r2   r3   dtypefloat16float32float64bfloat16ry   rz   r   r   )r   ry   r   r   r   _is_fp  s    r   c                 C  sH   t |tjrJ 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
    rc   r   rd   )r1   r2   r3   r    rh   ri   double)rP   scalarr   r   r   _generate_wrapped_number&  s    
r   c              
   C  s   |d urt dd | d|}| d|| jdtj|gtjdd}t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   rc   r   rd   
   Ascending is not supportedTopK   r   outputs)r   	largest_ir   )r   rh   r2   ri   int64r   r   )rP   r   r   Z	decendingoutZshape_Z	dim_size_r   r   r   _sort_helper8  s    


r   c              	   C  s   |d urt dd t|s8| jdtj|gtjdd}n>t| || jdtdgd}t|dkrv| jd|tj	j
d	}tjd
kr|st dd | jd|||ddS | jd|||||ddS d S )Nr   r   rc   r   rd   rC   r   r   r   r   r   r   r   )r   r   Zsorted_ir   )r   r$   rh   r2   ri   r   r   r   r   TensorProtoDataTypeINT64r   r   )rP   r   kr   largestsortedr   r   r   r   _topk_helperK  s    


r   c                 C  s>   t jdkr"ddlm} || ||S ddlm} || ||S d S )N   r   )lt)r   r   Ztorch.onnx.symbolic_opset8r   r   )rP   r   otherZ_lt8Z_lt9r   r   r   
_lt_helper^  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   r(   )interpolate_modeZonnx_opr   r   r   _interpolate_warningi  s    r   c                 C  s   t |d rNtjdkr>| jdtj|tjdd}| d||S | jd||dS tjdk rntd| 	  | d||d S )	Nr      rc   r   rd   Z	Unsqueezeaxes_iz=Opset version must be >= 13 for Unsqueeze with dynamic axes. )
r7   r   r   rh   r2   ri   long
ValueErrorr#   sourceRange)rP   r   r   r   r   r   r   _unsqueeze_helperz  s    

r   c                 C  s   t |d rNtjdkr>| jdtj|tjdd}| d||S | jd||dS tjdk rntd| 	  |d }t
|}|d	krtd
n$|dkrt| |dg}| d||S | d||S )Nr   r   rc   r   rd   Squeezer   z;Opset version must be >= 13 for Squeeze with dynamic axes. rC   zCFor Squeeze axses as input, the axes rank must be one in ONNX spec.)r7   r   r   rh   r2   ri   r   r   r#   r   r   r   )rP   r   r   r   Zaxes_tZ	axes_rankr   r   r   _squeeze_helper  s&    

r   rC   c                 C  sv   t |d}t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   rc   r   rd   Z	ReduceSum)
keepdims_inoop_with_empty_axes_i)r   r   )r0   r   r   r$   rh   r2   ri   r   )rP   r   r   r   r   r   r   r   _reducesum_helper  s*    

r   c                   s   t dtrd}| jdtj|tjdd}| jdtd d}t| | d	d
gtj	g|gd}| jd|td d}| d||}| jd||d
d}	n6 fddt
d
 D }
| jdtj|
tjdd}	|	S )Nr   r   rc   r   rd   r   r   r   r   r   r   r   r   DivConcatr   c                   sD   g | ]<}|d k rdn*t  |   t    |    qS )r         ?)r    ry   r   r   r   r   r   output_sizer   r   r     s   z/_interpolate_size_to_scales.<locals>.<listcomp>)r0   r$   rh   r2   onesr   r   r   sysmaxsizerangeri   )rP   r   r  r   offsetoffsetsdividenddivisorZ
scale_dimsscalesZscales_constantr   r  r   _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   rc   r   r   rd   r   r   )r0   r   rh   r2   r  r   ri   )rP   r  Zavailable_scalesr  Zscales_listr   r   r   $_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   rC   )r  )rP   moderQ   align_cornersr  r   r   r   _get_interpolate_attributes  s    
r  c                   s   | j dtjdtjdd}t }t  tjsB|d urT|dkrT| j d| ddS t	|  dg | j d t
d	 d
  fddt|d D }| j d|g|R ddi  S )Nrc   r   r   rd   r   r   r   r   r   r   c                   s   g | ]} qS r   r   r   scale_factorr   r   r     r   z+_interpolate_get_scales.<locals>.<listcomp>r   )rh   r2   r  r   r   r1   ry   r   r   r   r   r  )rP   r  r   r  Zscale_factor_rankr  r   r  r   _interpolate_get_scales  s    r  c                   s  t |d}d|v rd}d|v r"d}t| t |d}t|trL|rLtddS |  sbtddS |  }t|st| ||}nt st	 st  d d	k}|rt
|  d	g  fd
dt|d D  | jdg R dd	i t| | |}n
tddS ||fS )Nr   linearcubicr   interpolatezalign_corners == Truemissing input shaper   r   c                   s   g | ]} qS r   r   r   r   r   r   r     r   z4_interpolate_get_scales_and_mode.<locals>.<listcomp>r   r   r   z.Both size and scales are None in __interpolate)r0   r   r1   r'   r   ry   r   r   r  rB   r   r  rh   r  )rP   r   r   r  r  r  r   	is_scalarr   r  r    _interpolate_get_scales_and_mode  s4    



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 u r| d|}t| |dgdgdgd}| jd	|td
 d}| jd||dd}t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 t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  pytorch_half_pixelr   r   r   r   r   r   r   r   r   r   rc   r   rd   Resize      floorZ coordinate_transformation_mode_sZcubic_coeff_a_fZmode_sZnearest_mode_s)r  r6   rh   r   r   r   r   "_optional_input_placeholder_tensorr2   ri   r   )rP   r   r  rQ   r  r  coordinate_transformation_mode
input_sizeZinput_size_beg	empty_roiempty_scalesr   r   r   r     sd    


z(_interpolate_helper.<locals>.symbolic_fn)rr   )r   r   r   r   r   r'  r   _interpolate_helper  s    
<r(  c                   s:  t |d}d|v rd}d|v 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y   t  }	|	st	
d Y n0 |	r0t|}
|
d u rtddS t|  dg  fddt|
d D  | jdg R ddi | jd td d | jd| dd tjdkrtt| }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 u rtd"d#S tjdkrt| }n| jdtjg tjdd}t| ||
}| jd||||d|d d!S d S )$Nr   r  r  r   Fr  r  r  r  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 r   r   r   r  r   r   r     r   z(__interpolate_helper.<locals>.<listcomp>r   r   r   r   r   r   r   rc   r   rd   r  r  r   r!  zinterpolate (with scales)r  )r0   r1   r'   r   rh   r   rB   r   AttributeErrorr   r   r   r   r   r  r   r   r   r"  r2   ri   r   r  )rP   r   r   r  r  r  recompute_scale_factorr#  r$  r  rankr%  r&  r  r   r  r   __interpolate_helper_  s    









r,  c                 C  sJ   t jdk rddlm} n$t jdkr0ddlm} nddlm} || |||S )N   r   )unbind   )r   r   r   r.  torch.onnx.symbolic_opset11torch.onnx.symbolic_opset13)rP   r}   r   rG   r.  r   r   r   _unbind_helper  s    

r2  c                 C  s4   t jdkrddlm} nddlm} || ||||S )Nr   r   scatter)r   r   r   r4  r0  )rP   r}   r   r   srcr4  r   r   r   _scatter_helper  s    
r6  c                 C  sp   t 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/  SplitrC   )Zsplit_ir   r   r   )splitrc   rd   )rG   )r   r   rh   r1  r8  r2   ri   )rP   r}   repsr   Z	split_outr8  repeatsr   r   r   _repeat_interleave_split_helper  s    
r;  c                 C  s   dd }|d u s t |rLt|rL||||gr<ttj}qPtt }n|}|rh| jd|t| dnd }|r| jd|t| dnd }|r| jd|t| dnd }||||fS )Nc              	   S  s>   | D ]4}z|   dkr"W  dS W q ty6   Y q0 qdS )Nr   FT)ry   rz   rN   )scalarsr   r   r   r   _is_all_integral  s    z-_arange_cast_helper.<locals>._is_all_integralr   r   )	r$   r   scalar_type_to_pytorch_typer   r2   r   get_default_dtyperh   scalar_type_to_onnx)rP   endstartstepr   r=  ry   r   r   r   _arange_cast_helper  s    rD  c                 G  s4   t jdkrddlm} nddlm} || g|R  S )Nr   r   )arange)r   r   r   rE  r0  )rP   rQ   rE  r   r   r   _arange_helper  s    
rF  c                 C  s8   |  d|}ddlm} || || j dtdgd|S )Nr   r   )selectrc   rd   )rh   r   rG  r2   ri   )rP   r}   r   
full_shaperG  r   r   r   _size_helper  s    rI  c           
   	     s   ddl m} tjdkr$ddl m} nddlm} |  d u rJtddS |  }t	|d t
| | fdd	t|D }|| | d
|dt
| |dg| d
|}|| ||d }	||	fS )Nr   )expandr   r3  
index_fillzinput rank not accesibler   c                   s   g | ]}| kr|qS r   r   r   	dim_valuer   r   r     r   z._index_fill_reshape_helper.<locals>.<listcomp>r   )r   rJ  r   r   r4  r0  ry   r   r   r/   r   r  rh   )
rP   r}   r   r   rJ  r4  self_dimZunsqueezed_indexZexpanded_index_shapeZexpanded_indexr   rL  r   _index_fill_reshape_helper  s     


$rO  c                 C  sj   t |d}t|s&| jdt|d}tjdkrT|dkrFtdtjd| d||S | jd|||d	S d S )
Nr   rc   rd   r   rC   zReshape with allowzero=1   Reshape)Zallowzero_i)r0   r$   rh   r2   r   r   r   r   )rP   r   r4   Z	allowzeror   r   r   r   &  s    

r   c              	   C  st  ddl m} t|d}t|d}|d u s0t|rt|d u r@tdtdg| d|   d }	| j	d|	d	}|d u st|r|d u rtdtd
g| d|   d }
| j	d|
d	}|d u st|s|d u st|rh|d ur|d usJ t
| || j	dtj||dgtjdd	}| j	d|g dd}|| || j	dtjddgtjdd	dd\}}||||fS )Nr   )	_var_meanrC   z@Unsupported: ONNX export of batch_norm for unknown channel size.r   ztorch.r3   rc   rd   g        r   r   	Transpose)r   r   rC   )Zperm_iF)r   rR  r   r   r)   r2   ri   ry   rz   rh   r   r   )rP   r   weightbiasrunning_meanrunning_varrR  
batch_sizeZchannel_sizeZweight_valueZ
bias_valueZ
reshape_inZtrans_inr   r   r   _batchnorm_helper4  s^    

rY  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#   r&   r   rk   )rZ  r[  kernel_sizestrider\  r   r   r   r   _avgpool_helperg  s    
r_  c                 C  sl   | dkrdnd} t jd urh| t jkrh| r,dnd}t jr:dnd}td| d | d | d	 | d
  d S )NrC   TFz	training 	inferencezONNX export mode is set to z mode, but operator z is set to z) mode. The operators will be exported in z*, as specified by the functional operator.)r   training_moder   r   )Zop_train_moder   Zop_modera  r   r   r   check_training_modet  s.    rb  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	g|R d
di}	ddlm}
 |
| ||	S )Nr   r   )r   r   r   rc   r   r   rd   rC   r   r   )_reshape_from_tensor)rh   r   r2   ri   r   r   rc  )rP   r   	start_dimend_dimr   r$  slice1slicesslice3final_shaperc  r   r   r   _flatten_helper  s     rj  c                 C  s,   |d u rdS t | r(|   dkr(dS dS )NFr   TrA   )Zsplit_size_or_sizesrG   r   r   r   _is_split_static  s    rk  c                 C  s   |  d}|tj  |S )Nr   )rh   setTyper   OptionalTypeofTensor)rP   nr   r   r   r"    s    
r"  c                   sJ   t  }|d ur:t fddt|D r:| j| ddS | j| ddS )Nc                   s   g | ]}t  |d kqS )r   )r   r   r}   r   r   r     r   z+_handle_reduce_dim_none.<locals>.<listcomp>rC   )r   r   )r   rl   r  rh   )rP   r}   r   r+  r   rp  r   _handle_reduce_dim_none  s    
rq  z(Optional[torch.onnx.TensorProtoDataType]z7Tuple[_C.Value, _C.Value, _C.Value, Optional[_C.Value]])qtensorqdtyper:   c                 C  s   t |}|dd \}}}t|dkr.|d nd}t|dd}t|   }	|du rl|	durd|	}ntjj}| j	d||d}
| j	d|tjj
d}| j	d||d}|durtjdk rtd	tjdd
 | j	d	|
|||d|||fS )at  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.
    Nr      r   axisr   r   r   ZDequantizeLinear Attribute axis is not supported.r   )r@   rH   r8   r   ry   rz   r   r   UINT8rh   FLOATr   r   r   )rP   rr  rs  Zunpacked_qtensorsri   r_   r`   ru  r   Zinput_qdtyper   r   r   r   rm     s0    rm   zOptional[_C.Value])ri   r_   r`   ru  r:   c              	   C  s   |dur*t |s*tjdk r*tdtjdd |dus6J |  dkrZ| jd|tjj	d}|dusfJ |  dvr| jd|tjj
d}| jd|||t|d	d
d}|||g}|durt |s|| | jdg|R  S )a  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.
    Nr   ZQuantizeLinearrv  r   r   r   )ByteCharr   ru  r   r>   )r   r   r   r   ry   rz   rh   r   r   rx  rw  r8   rn   )rP   ri   r_   r`   ru  rq   rQ   r   r   r   ro     s:    


ro   c           
      C  s   |  d||}|  d|}| j d|tjdgtjdd}| j d|  d||tjjd	}g }	|d
urtt|st|	| | j d|||g|	R  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.
    Mulr   ZConstantOfShaper   r   rd   r   r   r   Nr>   )	rh   r2   ri   r   r   r   INT32r   rn   )
rP   rU  Zinput_scaleweight_scaleru  Z
bias_scaleZbias_scale_shapeZbias_zero_pointZq_biasZ	axis_argsr   r   r   requantize_bias_helper  s    
r~  c                   s2   | sJ | d     t fdd| D }|S )Nr   c                 3  s   | ]}|    kV  qd S r   )ry   rz   )r   elem
base_dtyper   r   rf   2  r   z'args_have_same_dtype.<locals>.<genexpr>)ry   rz   all)rQ   Zhas_same_dtyper   r  r   args_have_same_dtype/  s    r  r   opset_versionc                 C  s
   | t _d S r   )r   r   r  r   r   r   _set_opset_version7  s    r  c                 C  s
   | t _d S r   )r   r   )r   r   r   r   _set_operator_export_type;  s    r  c                 C  s
   | t _d S r   )r   ra  )ra  r   r   r   _set_training_mode?  s    r  onnx_shape_inferencec                 C  s
   | t _d S r   )r   r  r  r   r   r   _set_onnx_shape_inferenceE  s    r  )ry  rz  r   r   r   r   r   ShortBoolComplexFloatComplexDoubler   	Undefinedry  rz  r   r   r   r   r   r  r  r  r  QInt8QUInt8QInt32r   )uint8_tint8_tr   r    halfr   int64_tint16_tr'   	complex64
complex128qint8quint8qint32r   c                   @  s   e Zd ZdZdZe Ze Ze Z	e Z
e Ze Ze Ze Ze Ze Ze Ze Ze Ze Ze ZdS )
ScalarTypezAA human-readable name for a key into scalar_type_to_pytorch_type.r   N)rI   
__module____qualname____doc__rw  enumautoINT8SHORTINTr   HALFrx  DOUBLEZ	COMPLEX32	COMPLEX64
COMPLEX128BOOLZQINT8ZQUINT8ZQINT32BFLOAT16r   r   r   r   r  r  s"   r  )ry  rz  r   r   r   r   r   r  r  r  r  r  r  r  r   c                 C  s   |j d|| dS )Nr   r   )rh   )r   rP   r   non_blockingr   r   r   _cast_func_template  s    r  r  zSet[int]_quantized_ops)NN)T)T)NF)TN)TFN)NrC   r   )NNN)r   )N)N)N)
__future__r   r  rX   rJ   r  r   typingr   r   r   r   r   r   r	   r
   r2   Ztorch._C._onnxr   _onnxr   
torch.onnxr   Ztorch.onnx._globalsr   r/   r0   r6   r8   r=   r@   rB   r^   rr   rw   r   r   r$   r7   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  r  r  r  r  r(  r,  r2  r6  r;  rD  rF  rI  rO  r   rY  r_  rb  rj  rk  r"  rq  rm   ro   r~  r  r  r  r  r  r   rw  r  r  rx  FLOAT16r|  r   INT16r  r  r  r  	UNDEFINEDr   r   IntEnumr  uint8int8shortr   r   r  r    r   	complex32r  r  r'   r  r  r  r   r>  Zpytorch_name_to_typer  r@  setr  __annotations__r   r   r   r   <module>   sR  (2
6
K[
	
				




!A]
	
!
3 2 3
