o
    wZhh!                     @   s*  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
 ejjjZed dev r7eeee	e
gr7e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_TSAN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   W/var/www/auris/lib/python3.10/site-packages/torch/testing/_internal/common_quantized.py_conv_output_shape   s   r   c                 C   s^   |du r
t |j}|du 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   
multiplierr   r   r   Zqtyper   r   r   r   _requantize+   s   r$   Fc                 C   sP  |t jt jfv s
J |t jkr|t jksJ t| t jr |  } |t jkr1|r,d\}}nd\}}n|r8d\}}nd\}}|  }|  }|t jk}||krRd}	d}
nN|rrt|| }| }|| ||  }	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_symmetricZ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_qparams2   s@   









r6   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 ]U}|  }|  }	||	krOd||< d||< q8t|	d}	t|d}|	| | ||< t|| ttjj||< |t|||   ||< t||| ||< t||| ||< q8||fS )r%   r   )r   r(   r)   )r,   r*   r-   r.   r   r   r   r   ZzerosshapeZfloat64r   ranger/   r0   r1   r   )
r3   r   r   r   Zn_levelsr   r   ir4   r5   r   r   r   &_calculate_dynamic_per_channel_qparams[   s(   


r:   c                    s   t  ttfr!t tksJ  fddtt D }|S jr(  jr/      }|dkrBd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
    c                    s   g | ]}t  | | qS r   )_snr).0idxr   x_hatr   r   
<listcomp>   s    z_snr.<locals>.<listcomp>r   r)   inf   )
r,   listtuplelenr8   Zis_quantizedZ
dequantizeZnormr    log10)r   r?   resnoisesignalZsnrZsnr_dbr   r>   r   r;   u   s   
r;   c                 c   s:    t jjj}| t jj_zd V  W |t jj_d S |t jj_w Nr*   backends	quantizedZengine)qenginepreviousr   r   r   override_quantized_engine   s   

rP   c                 c   sB    z| r	t j  d V  W | rt j  d S d S | r t j  w w rJ   )r*   Z_CZ!_set_default_mobile_cpu_allocatorZ#_unset_default_mobile_cpu_allocator)qengine_is_qnnpackr   r   r   "override_cpu_allocator_for_qnnpack   s   
rR   c                    s    fdd}|S )Nc               	      sD   t D ]}t|  | i | W d    n1 sw   Y  qd S rJ   )supported_qenginesrP   )argskwargsrN   	qfunctionr   r   test_fn   s   
z"override_qengines.<locals>.test_fnr   )rW   rX   r   rV   r   override_qengines   s   rY   c                   C      t jjjdkS )NZfbgemmrK   r   r   r   r   qengine_is_fbgemm      r[   c                   C   rZ   )Nr   rK   r   r   r   r   rQ      r\   rQ   c                   C   rZ   )NZonednnrK   r   r   r   r   qengine_is_onednn   r\   r]   c                   C   rZ   )Nx86rK   r   r   r   r   qengine_is_x86   r\   r_   c                 C   s6   t t|  }d||< ||d< | t|}||fS )Nr   )rC   r8   dimpermuterD   )r3   axisZnew_axis_listyr   r   r   _permute_to_axis_zero   s
   rd   c              	   C   s   | j }t| tj|\} }t| }t|  d D ]"}	tt	| |	 d||	   ||	  ||||	  ||	  ||	< q|
t|}
|
|S Nr   r(   )r   rd   tor*   r0   
zeros_liker8   sizeclampr   ra   rD   )r3   per_channel_scaleper_channel_zero_pointrb   	quant_min	quant_maxr   permute_axis_listrG   r9   outr   r   r   +_fake_quantize_per_channel_affine_reference   s   


rp   c                 C   s   |j }t|tj|\}}t|}	t| d D ]}
t||
 d||
   ||
  |	|
< q|		t
|}	|	|k|	|k }t| }| | ||< ||S re   )r   rd   rf   r*   r0   rg   r8   rh   r   ra   rD   )ZdYr3   rj   rk   rb   rl   rm   r   rn   ZXqr9   maskrG   r   r   r   0_fake_quantize_per_channel_affine_grad_reference   s   
(

rr   c                 C   s:   t | tjst| } n|   } | jt|tjdS )N)devicer   )	r,   r*   r-   Ztensordetachclonerf   rs   r0   )r3   rs   r   r   r   	to_tensor   s   rv   )r   )%__doc__r.   r   r*   
contextlibr   Z$torch.testing._internal.common_utilsr   r   r   r   rL   rM   Zsupported_enginesrS   removeanyr   Zuint8r   r!   r$   r+   r6   r:   r;   rP   rR   rY   r[   rQ   r]   r_   rd   rp   rr   rv   r   r   r   r   <module>   s<   



)

	