o
    0hh!                     @   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)
input_sizekernel_sizepaddingstridedilationoutput_padding r   \/var/www/vscode/kcb/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!   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_affineper_tensor_symmetricqint8
isinstanceTensornumpyr   r   r   finfofloat32epsr   r%   int)Xr"   reduce_rangeqschemer    r!   min_valmax_valis_symmetricr   r   r   r   r   _calculate_dynamic_qparams2   s@   









rA   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/   )r4   r0   r5   r6   r   r   r   r   zerosshapefloat64r   ranger7   r8   r9   r   )
r;   r"   r    r!   n_levelsr   r   ir>   r?   r   r   r   &_calculate_dynamic_per_channel_qparams[   s(   


rH   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   )
r4   listtuplelenrE   is_quantized
dequantizenormr%   log10)r   rM   resnoisesignalsnrsnr_dbr   rL   r   rI   u   s   
rI   c                 c   s:    t jjj}| t jj_zd V  W |t jj_d S |t jj_w Nr0   backends	quantizedengine)qenginepreviousr   r   r   override_quantized_engine   s   

rd   c                 c   sB    z| r	t j  d V  W | rt j  d S d S | r t j  w w r]   )r0   _C!_set_default_mobile_cpu_allocator#_unset_default_mobile_cpu_allocator)qengine_is_qnnpackr   r   r   "override_cpu_allocator_for_qnnpack   s   
ri   c                    s    fdd}|S )Nc               	      sD   t D ]}t|  | i | W d    n1 sw   Y  qd S r]   )supported_qenginesrd   )argskwargsrb   	qfunctionr   r   test_fn   s   
z"override_qengines.<locals>.test_fnr   )rn   ro   r   rm   r   override_qengines   s   rp   c                   C      t jjjdkS )Nfbgemmr^   r   r   r   r   qengine_is_fbgemm      rs   c                   C   rq   )Nr   r^   r   r   r   r   rh      rt   rh   c                   C   rq   )Nonednnr^   r   r   r   r   qengine_is_onednn   rt   rv   c                   C   rq   )Nx86r^   r   r   r   r   qengine_is_x86   rt   rx   c                 C   s6   t t|  }d||< ||d< | t|}||fS )Nr   )rQ   rE   dimpermuterR   )r;   axisnew_axis_listyr   r   r   _permute_to_axis_zero   s
   r~   c              	   C   s   | j }t| tj|\} }t| }t|  d D ]"}	tt	| |	 d||	   ||	  ||||	  ||	  ||	< q|
t|}
|
|S Nr   r.   )r"   r~   tor0   r8   
zeros_likerE   sizeclampr   rz   rR   )r;   per_channel_scaleper_channel_zero_pointr{   	quant_min	quant_maxr"   permute_axis_listrX   rG   outr   r   r   +_fake_quantize_per_channel_affine_reference   s   


r   c                 C   s   |j }t|tj|\}}t|}	t| d D ]}
t||
 d||
   ||
  |	|
< q|		t
|}	|	|k|	|k }t| }| | ||< ||S r   )r"   r~   r   r0   r8   r   rE   r   r   rz   rR   )dYr;   r   r   r{   r   r   r"   r   XqrG   maskrX   r   r   r   0_fake_quantize_per_channel_affine_grad_reference   s   
(

r   c                 C   s:   t | tjst| } n|   } | jt|tjdS )N)devicer"   )	r4   r0   r5   tensordetachcloner   r   r8   )r;   r   r   r   r   	to_tensor   s   r   )r   )%__doc__r6   r   r0   
contextlibr   $torch.testing._internal.common_utilsr   r   r   r   r_   r`   supported_enginesrj   removeanyr   uint8r$   r&   r*   r1   rA   rH   rI   rd   ri   rp   rs   rh   rv   rx   r~   r   r   r   r   r   r   r   <module>   s<   



)

	