U
    dZ                     @   s  d dl Z d dlZd dl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 d dl	mZ d dlmZ dd	 Zed
d
ddd Zdd Zed
ddddSddZed
d
dddddTddZdd ZedejjjjdddZedejjjjdddZedejjjjdddZed ejjjjdd!dZ ed"ejjjjdd!dZ!ed#ejjjjdd!dZ"d$d% Z#e#d&ejjjjZ$e#d'ejjjjZ%e#d(ejjjjZ&d)d* Z'e'd+dd,Z(e'd-d.d,Z)e'd/d0d,Z*e'd1dd2Z+e'd3d.d2Z,e'd4d0d2Z-d5d6 Z.dUd7d8Z/d9d: Z0ed
d;d<d= Z1d>d? Z2ed
d
d
dddd
dd	d@dA Z3ed
d
d
dddVdDdEZ4dFdG Z5dHdI Z6dJdK Z7dLdM Z8ed
dNdNdNdOdP Z9G dQdR dRZ:dS )W    N)Sequence)_C)_patch_torch)symbolic_helper)symbolic_opset9)GLOBALSc                 G   s0   t |dkrt| ||S t| ||f| S d S Nr   )lenopset9true_divide_div_rounding_mode)gselfotherargs r   ?/tmp/pip-unpacked-wheel-ua33x9lu/torch/onnx/symbolic_opset10.pydiv   s    r   vsc                 C   s(   |dkrt | ||S t| |||S d S )Nfloor)_floor_divider
   r   )r   r   r   Zrounding_moder   r   r   r       s    r   c                 C   s   t |st |r.t| ||}| d|S | d||}| jdtjdtjdd}| d| d||| d||}| jd	||dd
}| d|| d| d||}| jdtjdtjdd}	| d||	}
| d||
|S d S )NZFloorZDivConstantr   dtypeZvalue_tZXorZLessModZfmod_iAndZNotZEqual   ZSubWhere)r   _is_fpr
   r   optorchtensorZint64)r   r   r   outr   ZzeronegativemodZ
fixup_maskZonefixupr   r   r   r   (   s    " r   inonec                 C   s   t j| ||||dS )N)	decendingr%   )r   Z_sort_helper)r   r   dimr+   r%   r   r   r   sort<   s    r-   c              	   C   s   t j| ||||||dS )N)largestsortedr%   )r   Z_topk_helper)r   r   kr,   r.   r/   r%   r   r   r   topkA   s          r1   c              	      s<   t ddddddt dddddd fdd}|S )NTFr   isr)   c                    s   |s|}||d ||d}t |dhkrD||d< r| jd|fddi|\}}	| jd|ddd t D d	d t D d
\}
}tj| |dd t D ddd}t| |	|}	||	fS | jd|fddi|}|S d S )N   )kernel_shape_ipads_i	strides_iceil_mode_ir   Zdilations_iZMaxPooloutputsc                 S   s   g | ]}d qS r   r   .0_r   r   r   
<listcomp>i   s     z2_max_pool.<locals>.symbolic_fn.<locals>.<listcomp>c                 S   s   g | ]}d qS r9   r   r:   r   r   r   r=   j   s     )r8   r4   r6   c                 S   s   g | ]}d | qS )r3   r   )r;   r)   r   r   r   r=   p   s     r   )axesstartsends)setr"   ranger   _slice_helperr
   sub)r   inputkernel_sizestridepaddingdilation	ceil_modekwargsrindicesr<   Zflattened_indicesr   ndimsreturn_indicestuple_fnr   r   symbolic_fnI   s:    

z_max_pool.<locals>.symbolic_fn)r   quantized_args
parse_args)namerQ   rO   rP   rR   r   rN   r   	_max_poolH   s    /rV   
max_pool1dr   F)rP   
max_pool2dr3   
max_pool3d   max_pool1d_with_indicesTmax_pool2d_with_indicesmax_pool3d_with_indicesc              
      s^   t dddddddt dddddddd
tjtt tt tt ttd fdd	}|S )NTFr   r2   r)   r*   )rE   rF   rG   rH   rJ   count_include_padc           	   	      sr   |s|}t |||| }|rLtj| d|d| d dddd}dt| }| jd	||||d |d
}|S )NZPad)r   r   r3   Zconstant           )r5   mode_sZvalue_fZopset_beforer   ZAveragePool)r4   r6   r5   r7   )r   Z_avgpool_helperr
   Zop_with_optional_float_castr	   r"   )	r   rE   rF   rG   rH   rJ   r^   Zdivisor_overrideoutputrU   rQ   r   r   rR      s<         
	z_avg_pool.<locals>.symbolic_fn)N)r   rS   rT   r   Valuer   int)rU   rQ   rR   r   rd   r   	_avg_pool   s    	 $rg   
avg_pool1d
avg_pool2d
avg_pool3dc                    s"   t ddd fdd}|S )NTFc                    s`   t | |\}}t  t |}|r6t dS |d krNt | || }| jd||dS )Nzalign_corners == TrueResizera   )r   Z_get_interpolate_attributesZ_interpolate_warning_maybe_get_scalarZ_unimplementedZ_interpolate_size_to_scalesr"   )r   rE   Zoutput_sizer   scalesalign_cornersr,   interpolate_moderU   r   r   rR      s"      

   z!_interpolate.<locals>.symbolic_fn)r   rS   )rU   r,   rq   rR   r   rp   r   _interpolate   s    rr   upsample_nearest1dZnearestupsample_nearest2d   upsample_nearest3d   upsample_linear1dlinearupsample_bilinear2dupsample_trilinear3dc           	      C   s*   t | |||||\}}| jd|||dS )Nrk   rl   )r   Z _interpolate_get_scales_and_moder"   )	r   rE   sizeZscale_factormodero   Zrecompute_scale_factorZ	antialiasrn   r   r   r   __interpolate   s         r~   c                 C   s`  |rTt | |dg}t | |dg}t|trB| jdt|d}t | |dg}nt|t|kshtt|t|ks|t|d kst|t|kstt|dkr|d dkr|d dkr|d kst|dkr|d dkr|S | jdt|d}| jdt|d}| jdt|d}|d kr8| d||||S | jdt|d}| d|||||S )Nr   r   r   r       Slice)	r   _unsqueeze_helper
isinstancerf   r"   r#   r$   r	   AssertionError)r   rE   r>   r?   r@   stepsdynamic_slicer   r   r   _slice   s:    






r   c              	   G   sv  t |dkr|\}}}}n$t |dkr6|\}}}d}ntd|  dko\|  dk}|  dko||  dk}|  dk}	|  dk}
t|d}|s|	rt|ts|s|
rt|ts|  dkrd	}|r| j	d
t
dd}|r\| j	d
t
dd}nB|r$dn
t|dg}|r<dn
t|dg}t|dg}d}tj| |||||g|dS )Nru   rZ   r   zUnknown aten::slice signaturezprim::ConstantZNoneTypezonnx::Constantr)   Tr   r   r   F)r>   r?   r@   r   r   )r	   NotImplementedErrornodekindtyper   Z
_parse_argr   rf   r"   r#   r$   rC   )r   r   r   r,   startendstepZis_start_noneZis_end_noneZis_start_onnx_constZis_end_onnx_constr   r   r   r   slice   s\    
r   r2   c              	   C   s4   t j| ||dgt| dgt| dgt| dS )Nl )r>   r?   r@   r   )r   rC   r	   )r   rE   Zdimsr   r   r   flip.  s    r   c                 C   s   | j d||ddS )Nr   r   r   )r"   )r   rE   r   r   r   r   fmod:  s    r   c
                 C   s  |rt jrtdS |	d k	r,|	dkr,tdtd t|d}
|
d k	r|r^|
d }|}n4|
}|| jdt	
tjgdg}| jd|d	di}g }t|D ]8}t| t| |t	
dt	
|dg}t| t| |t	
dt	
|d dg}| jdt	
dgd}| d
||||}| d||}t|sj| d
||||}t| |dg}| d||}|dkrtj| |dgdd}n4|dkr| jd|dgdd}n| jd|dgdd}t| |dg}|| q| jd|d	di}|d d d fS tdS d S )Nz7embedding_bag with scale_grad_by_freq for training moder   zembedding_bag with padding_idxzExport of embedding_bag with dynamic input/offsets shape is not supported in opset 10. Please use opset 11 or higher to export model for dynamic input shape.'r   r   r   Concataxis_ir   ZGatherZMul)Zaxes_iZ
keepdims_iZ
ReduceMeanZ	ReduceMaxziembedding_bag with unknown shape of offsets for opset 10 is not supported. please use opset 11 or higher.)r   )r   )r   Ztraining_moder   Z_onnx_unsupportedRuntimeErrorwarningswarnZ_get_tensor_dim_sizer"   r#   r$   sysmaxsizerB   r   r
   selectZ_is_noneZ_reducesum_helperappend)r   Zembedding_matrixrM   offsetsZscale_grad_by_freqr}   sparseZper_sample_weightsZinclude_last_offsetZpadding_idxZoffsets_dim_0Z
offset_lenZoffsets_extendedlist_r)   Zstart_end_Zaxes_Zindices_rowZ
embeddingsZper_sample_weights_rowrc   r   r   r   embedding_bag>  s    

         
   
r      c              	   C   s   ||fdkrt dddd ||fdkr8td||t |}|d krZt dddd | j}|d	kr| jd
|tj	j
d}n| jd
|tj	jd}| d| d|||||S )N)r   r   fake_quantize_per_tensor_affine
      z=Quantize range (0, 127) not supported, requires opset 13 Clip))r      )r   r   zSFor (quant_min, quant_max), ONNX allows only (0, 255) and (-128, 127). Got ({}, {})z Non-constant scale not supportedr   CastZto_iZDequantizeLinearZQuantizeLinear)r   Z _onnx_opset_unsupported_detailedr   formatrm   floatdatar"   _C_onnxTensorProtoDataTypeZUINT8ZINT8)r   inputsscale
zero_pointZ	quant_minZ	quant_maxr   r   r   r     s@     

r   c                 C   s   |  dt| |dS )NZIsInfF)r"   r
   Z_cast_Doubler   rE   r   r   r   isinf  s    r   c                 C   s8   ddl m}m} t| |}t| |}|| || ||S )Nr   )__not___or_)Ztorch.onnx.symbolic_opset9r   r   r   r
   isnan)r   rE   r   r   Zinf_nodeZnan_noder   r   r   isfinite  s    
r   c                 C   sH   t |dd}| jd|t j| d}| jd|tjjd}t | |||S )Nr)   r   r   r   )r   Z
_get_constr"   Zscalar_type_to_onnxr   r   FLOATquantize_helper)r   rE   r   r   r   r   r   r   quantize_per_tensor  s      r   c                 C   s   t | |d S r   r   dequantize_helperr   r   r   r   
dequantize  s    r   fc                 C   s0  t |s|S t j|   }|d kr,d}t| |}| d|| jdtj	|g|dd|}t
|}|d krv|j}t| t| |t| || jdtdgd}	| d|	| jdtj	|g|dd|}
|d kr|j}t| t| |
t| |
| jdtdgd}| d|| jdtj	|g|dd|
S )Nr_   r    r   r   r   r   )r   r!   Zpytorch_name_to_typer   Z
scalarTyper
   r   r"   r#   r$   finfomaxlogical_andr   gtZ
LongTensorminlt)r   rE   nanZposinfZneginfZinput_dtypeZnan_condZ
nan_resultr   Zposinf_condZnan_posinf_resultZneginf_condr   r   r   
nan_to_num  sV    
	
  r   c                   @   s   e Zd ZdZdZedd Zedd Zedd Zed	d
 Z	edd Z
edd Zedd ZeeddddejeejejejdddZdS )	Quantizedz
    https://github.com/pytorch/pytorch/wiki/PyTorch-ONNX-exporter#quantized-model-export

    Support starts from opset 10 because `DequantizeLinear` and `QuantizeLinear` were introduced in opset version 10.
    Z	quantizedc                 C   sl   t | |\}}}}t | |\}	}
}}t | |||
}t | |\}}}}t| ||	|}t | |||S N)r   r   requantize_bias_helperr
   ry   r   )r   q_inputq_weightbiasop_scaleop_zero_pointrE   input_scaler<   weightweight_scaleq_biasrc   r   r   r   ry     s       zQuantized.linearc                 C   sF   t | |\}}}}t | |\}}}}t| ||}t | |||S r   )r   r   r
   addr   r   xyr   r   r<   rc   r   r   r   r     s    zQuantized.addc                 C   sR   t | |\}}}}t | |\}}}}t| ||}t| |}t | |||S r   )r   r   r
   r   relur   r   r   r   r   add_relu&  s
    zQuantized.add_reluc                 C   sF   t | |\}}}}t | |\}}}}t| ||}t | |||S r   )r   r   r
   mulr   r   r   r   r   r   0  s    zQuantized.mulc                 C   s0   t | |\}}}}t| |}t | |||S r   )r   r   r
   	hardswishr   )r   r   r   r   r<   rc   r   r   r   r   9  s    zQuantized.hardswishc
              
   C   s   t | |\}
}}}t | |\}}}}t | |||}t | |\}}}}t| |
||||||}t| |}t | |||	S r   )r   r   r   r
   conv2dr   r   r   r   r   r   rG   rH   rI   groupsr   r   rE   r   r<   r   r   r   rc   r   r   r   conv2d_reluA  s*              zQuantized.conv2d_reluc
              
   C   st   t | |\}
}}}t | |\}}}}t | |||}t | |\}}}}t| |
||||||}t | |||	S r   )r   r   r   r
   r   r   r   r   r   r   r   \  s(              zQuantized.conv2dr   r)   )q_inputsr,   r   r   returnc                    s@   t |} fdd|D } jd|d|i}t  |||S )Nc                    s   g | ]}t  |d  qS rb   r   )r;   rE   r   r   r   r=     s    z!Quantized.cat.<locals>.<listcomp>r   r   )r   )r   Z_unpack_listr"   r   )r   r   r,   r   r   Zunpacked_inputsZdequantizedZconcatenatedr   r   r   catv  s    	

zQuantized.catN)__name__
__module____qualname____doc__domainstaticmethodry   r   r   r   r   r   r   r   rT   r   re   rf   r   r   r   r   r   r     s0   


	



r   )N)N)NF)r   r   );r   r   typingr   r#   Ztorch._C._onnxr   Z_onnxr   Z
torch.onnxr   r   r   r
   Ztorch.onnx._globalsr   r   rT   r   r   r-   r1   rV   nnmodulesutilsZ_singlerW   Z_pairrX   Z_triplerY   r[   r\   r]   rg   rh   ri   rj   rr   rs   rt   rv   rx   rz   r{   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s   

5 
   
   
   
   
   
  *	
/


T   &	
3