U
    Mh!                     @   s4  d Z ddlZddlZddlmZ ddlmZmZm	Z	m
Z
mZmZ ejjjZed dekrzee
eee	eegrzed d-ddZddejfd	d
Zdd ZddejfddZdejfddZdd Zdd Zedd Zedd Zdd Zdd Zdd  Z d!d" Z!d#d$ Z"d%d& Z#d'd( Z$d)d* Z%d+d, Z&dS ).z`Importing this file includes common utility methods for checking quantized
tensors and modules.
    N)contextmanager)TEST_WITH_ASANTEST_WITH_TSANTEST_WITH_UBSANIS_PPCIS_MACOS
IS_WINDOWSnoneqnnpackc                 C   s6   t | d|  | |d |d   | d|  d S )z7Computes the output shape given convolution parameters.      )npfloor)Z
input_sizeZkernel_sizepaddingZstrideZdilationZoutput_padding r   Z/var/www/html/venv/lib/python3.8/site-packages/torch/testing/_internal/common_quantized.py_conv_output_shape   s    r   c                 C   s^   |dkrt |j}|dkr(t |j}t | | | t j}t |||}||}|S )zQuantizes a numpy array.N)r   iinfominmaxroundastypeint64clip)xscale
zero_pointqminqmaxdtypeqxr   r   r   	_quantize   s    
r!   c                 C   s   |  t| | }|S )zDequantizes a numpy array.)r   float)r    r   r   r   r   r   r   _dequantize&   s    r#      c                 C   s(   | |   | }t||||}|S )zhRequantizes a numpy array, i.e., intermediate int32 or int16 values are
    converted back to given type)r   r   r   r   )r   Z
multiplierr   r   r   Zqtyper    r   r   r   _requantize,   s    r%   Fc                 C   sP  |t jt jfkst|t jkr,|t jks,tt| t jr@|  } |t jkrb|rXd\}}qxd\}}n|rpd\}}nd\}}|  }| 	 }|t jk}||krd}	d}
n|rt	|| }| }|| ||  }	t	|	t
t
jj}	d}
n\t	|d}t|d}|| ||  }	t	|	t
t
jj}	|t||	  }
t	||
}
t||
}
t|	t|
gS )xCalculate the dynamic quantization parameters (scale, zero_point)
    according to the min and max element of the tensor)i?   )i   )r   r(   )r   r$         ?r           )torchper_tensor_affineZper_tensor_symmetricAssertionErrorZqint8
isinstanceTensornumpyr   r   r   finfofloat32epsr   r"   int)Xr   Zreduce_rangeZqschemer   r   min_valmax_valZis_symmetricr   r   r   r   r   _calculate_dynamic_qparams3   s@    









r8   c           
      C   s$  t | tjr|  } t|jt|j }}|| }tj| j	d tj
d}tj| j	d tjd}t|j	d D ]}|  }|  }	||	krd||< d||< qpt|	d}	t|d}|	| | ||< t|| ttjj||< |t|||   ||< t||| ||< t||| ||< qp||fS )r&   r   )r   r)   r*   )r.   r+   r/   r0   r   r   r   r   ZzerosshapeZfloat64r   ranger1   r2   r3   r   )
r5   r   r   r   Zn_levelsr   r   ir6   r7   r   r   r   &_calculate_dynamic_per_channel_qparams\   s(    


r<   c                 C   s   t | ttfrTt| t|ks"tg }tt| D ]}|t| | ||  q2|S |jrb|	 }| jrp| 	 } | | 
 }|dkrdtdtdfS | 
 }|| }d|  }|||fS )a  Calculates the signal to noise ratio and returns the signal and noise
    power, as well as the SNR in dB.
    If the input is a list/tuple this function is called recursively on each
    element. The result will have the same nested structure as the inputs.

    Args:
        x, x_hat: Either a tensor or a nested list/tuple of tensors.
    Returns:
        signal, noise, SNR(in dB): Either floats or a nested list of floats
    r   r*   inf   )r.   listtuplelenr-   r:   append_snrZis_quantizedZ
dequantizeZnormr"   log10)r   Zx_hatresidxnoisesignalZsnrZsnr_dbr   r   r   rC   v   s"    rC   c                 c   s0   t jjj}| t jj_z
d V  W 5 |t jj_X d S Nr+   backends	quantizedZengine)qenginepreviousr   r   r   override_quantized_engine   s
    


rO   c                 c   s.   z| rt j  d V  W 5 | r(t j  X d S rI   )r+   Z_CZ#_unset_default_mobile_cpu_allocatorZ!_set_default_mobile_cpu_allocator)qengine_is_qnnpackr   r   r   "override_cpu_allocator_for_qnnpack   s    

rQ   c                    s    fdd}|S )Nc               
      s,   t D ]"}t|  | | W 5 Q R X qd S rI   )supported_qenginesrO   )argskwargsrM   	qfunctionr   r   test_fn   s    
z"override_qengines.<locals>.test_fnr   )rV   rW   r   rU   r   override_qengines   s    rX   c                   C   s   t jjjdkS )NZfbgemmrJ   r   r   r   r   qengine_is_fbgemm   s    rY   c                   C   s   t jjjdkS )Nr
   rJ   r   r   r   r   rP      s    rP   c                   C   s   t jjjdkS )NZonednnrJ   r   r   r   r   qengine_is_onednn   s    rZ   c                   C   s   t jjjdkS )Nx86rJ   r   r   r   r   qengine_is_x86   s    r\   c                 C   s6   t t|  }d||< ||d< | t|}||fS )Nr   )r?   r:   dimpermuter@   )r5   axisZnew_axis_listyr   r   r   _permute_to_axis_zero   s
    ra   c              	   C   s   | j }t| tj|\} }t| }t|  d D ]D}	tt	| |	 d||	   ||	  ||||	  ||	  ||	< q6|
t|}
|
|S Nr   r)   )r   ra   tor+   r2   
zeros_liker:   sizeclampr   r^   r@   )r5   per_channel_scaleper_channel_zero_pointr_   	quant_min	quant_maxr   permute_axis_listrE   r;   outr   r   r   +_fake_quantize_per_channel_affine_reference   s     
 
rm   c                 C   s   |j }t|tj|\}}t|}	t| d D ]*}
t||
 d||
   ||
  |	|
< q6|		t
|}	|	|k|	|k }t| }| | ||< ||S rb   )r   ra   rc   r+   r2   rd   r:   re   r   r^   r@   )ZdYr5   rg   rh   r_   ri   rj   r   rk   ZXqr;   maskrE   r   r   r   0_fake_quantize_per_channel_affine_grad_reference   s    
(
ro   c                 C   s:   t | tjst| } n|   } | jt|tjdS )N)devicer   )	r.   r+   r/   Ztensorclonedetachrc   rp   r2   )r5   rp   r   r   r   	to_tensor   s    rs   )r   )'__doc__r0   r   r+   
contextlibr   Z$torch.testing._internal.common_utilsr   r   r   r   r   r   rK   rL   Zsupported_enginesrR   removeanyr   Zuint8r!   r#   r%   r,   r8   r<   rC   rO   rQ   rX   rY   rP   rZ   r\   ra   rm   ro   rs   r   r   r   r   <module>   s:    


 
)

	