U
    d:                     @   s|   d dl Z d dlZd dlmZmZ d dlmZ d dlm	Z	 dddZ
d	d
 Zdd Zdd ZdddZdddZdddZdS )    N)utils	workspace)dnnlowp_pybind11)assumeF(\?c           	      C   s   |d kr| d d }|j dkr"d S tt|d}tt|d}|rbdtt|t| d }n|| d }|| }| dd  D ]$}tjj|d | d d |dd qd S )Nr            )atolZrtol)sizeminnpmaxabsZtestingZassert_allclose)	outputsrefZ	symmetricZ
atol_scaleZref_minZref_maxZ	ref_scaler
   o r   Q/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/quantization/server/dnnlowp_test_utils.pycheck_quantized_results_close   s    
r   c                 C   s,   ddl m} || \}}t|d t||S )z$s -> (s0,s1), (s1,s2), (s2, s3), ...r   )teeN)	itertoolsr   nextzip)iterabler   abr   r   r   pairwise!   s    
r   c	                 C   s  t | |fD ]\}	}
td|d d dD ]}||	|f | }||	|d f | }||
|f d | }||
|d f d | }|| ||  dk rdt||  | }t|d | ||
|d f< q*|| ||  dkr*dt||  | }t|d | ||
|d f< q*qt | |fD ]\}	}
td|d d dD ]}||	|f | }||	|d f | }||
|f d | }||
|d f d | }d|| ||    krdk s6n tq6qd S )Nr   r   r	            )r   ndindexrangefloatintAssertionError)
batch_sizeinput_channelsoutput_channelsXX_minX_maxWW_minW_maxijkx0x1w0w1w1_adjustedr   r   r   avoid_vpmaddubsw_overflow_fc+   s&     r8   c                    s  t 	}t fddt|D t	
fddt|D }t|f| |f D ]}|d }|d }|dd tt|f D ]\}}|d d |d }|d d |d }t 
fddt|D t 
fddt|D ||f |f  d	 | }||f |f  d	 | }t	fd
dt|D rv||f |f  |	 }n|	 }t	fddt|D r||f |f  |	 }n|	 }|| ||  dk rdt||  | }t|d	 | ||f |f < q|| ||  dkrdt||  | }t|d	 | ||f |f < qqZt|f| |f D ]}|d }|d }|dd tt|f D ]T\}}|d d |d }|d d |d }t 
fddt|D t 
fddt|D ||f |f  d	 | }||f |f  d	 | }t	fddt|D r||f |f  |	 }n|	 }t	fddt|D r||f |f  |	 }n|	 }d|| ||    krdk sn t	qqhd S )Nc                 3   s&   | ]} | | d   d  V  qdS r	   Nr   .0r0   )	dilationskernelsr   r   	<genexpr>]   s     z,avoid_vpmaddubsw_overflow.<locals>.<genexpr>c                 3   s6   | ].}| d |    |  |  d V  qdS r   r	   Nr   r:   )dkernelspadssizesstridesr   r   r>   ^   s    r   r	   c                 3   s6   | ].}| |  |   | |   V  qd S Nr   r:   r<   f0	o_spatialrA   rC   r   r   r>   n   s   c                 3   s6   | ].}| |  |   | |   V  qd S rE   r   r:   r<   f1rH   rA   rC   r   r   r>   r   s   r   c                 3   s.   | ]&}d  |   ko | k n  V  qdS r   Nr   r:   i0srB   r   r   r>   z   s     c                 3   s.   | ]&}d  |   ko | k n  V  qdS rK   r   r:   i1srB   r   r   r>      s     r   r!   r    c                 3   s6   | ].}| |  |   | |   V  qd S rE   r   r:   rF   r   r   r>      s   c                 3   s6   | ].}| |  |   | |   V  qd S rE   r   r:   rI   r   r   r>      s   c                 3   s.   | ]&}d  |   ko | k n  V  qdS rK   r   r:   rL   r   r   r>      s     c                 3   s.   | ]&}d  |   ko | k n  V  qdS rK   r   r:   rN   r   r   r>      s     )
lentupler#   r   r"   r   allr$   r%   r&   )rC   rA   r=   r<   rB   r(   r)   r'   r*   r+   r,   r-   r.   r/   ndimZ	size_colsZout_idxr   ocZfilter_idx1Zfilter_idx2Zic0Zic1r5   r6   r3   r4   r7   r   )r<   r@   rG   rJ   rM   rO   r=   rH   rA   rB   rC   r   avoid_vpmaddubsw_overflowL   s|    "$rU   c                    s<  t ttfdd| |fD  ttfddtD  || }|| }|dkoj|dk}|dksxt|dkst|rdnd}|d }|| }|r|
r|d }ttjj|ft	 |f  | |   
tj |dkr|r|
r|s jd d	kstt fd
dtdD s:t d j d  td f  d  }||dt	fddtdD  < ||ddggfddtdD  < tdD ]d}||dggfddtd|D  | d | d d gg fddt|d D  < qn(| d< |dkrF| d jd  d < |rVd}d}nd}|d }ttjj|ft	 |f  ||  | }|
tj}|
rLt|D ]}|||| fd|jd   < |r|||| dfd|jd   < n.|dkst|||| d fd|jd   < |s||| |d | f  |7  < qn,||dd|jd   < ||dd|jd   < |
o| }t|D ]r}t| |||| d|| |d | f ||||| |d | f ||r|nd ||r|nd  q|	dkrt  t|}tj|
tj} ||fS )Nc                 3   s   | ]}t | kV  qd S rE   )rP   )r;   r   )dimr   r   r>      s     z)generate_convnd_inputs.<locals>.<genexpr>c                 3   s.   | ]&}|  | | d   d  kV  qdS r9   r   r;   d)r<   r=   rB   r   r   r>      s     r	   r   ir   r      c                 3   s(   | ] } j |d   | d kV  qdS )r	   r   N)shaperW   )r*   r=   r   r   r>      s     )r   )r	   c                 3   s   | ]} | d  d V  qdS r?   r   rW   r=   r   r   r>     s     c                    s   g | ]} | d  dgqS r	   r   r   rW   r[   r   r   
<listcomp>  s     z*generate_convnd_inputs.<locals>.<listcomp>c                    s   g | ]} | d  d gqS )r   r	   r   r;   Zd2r[   r   r   r]     s     c                    s   g | ]} | d  dgqS r\   r   r^   r[   r   r   r]     s     ).r   id   i.ZNCHW)rP   r   rR   r#   r&   r   roundrandomZrandrQ   ZastypeZfloat32rZ   rS   slicerU   r   Z	NHWC2NCHWZrandn)rC   rA   r=   r<   rB   groupinput_channels_per_groupoutput_channels_per_groupr'   ordergroupwise_quantizationpreserve_activation_sparsitypreserve_weight_sparsityr(   r)   Zdepthwise_convolutionr+   r,   ZX_rangeZX_subd1r.   r/   r-   gZdifferent_range_per_groupr   r   )r*   r<   rV   r=   rB   r   generate_convnd_inputs   s    ""$($&	
   



rl   c                 C   s>   t | fd |fd |fd |fd |fd |||||	|
||S )Nr   )rl   )ZstridepadkernelZdilationr   rc   rd   re   r'   rf   rg   rh   ri   r   r   r   generate_conv_inputsV  s    ro   c              	   C   s\  |rt dddddg}nt ddddg}| jdj||	d | jdj||	d | jd	j||	d |d k	r|d k	rt| j td
t	|t
| W 5 Q R X |d k	r|d k	rt| j tdt	|t
| W 5 Q R X |r| j| t|dkr
dndD ]T}| j| | jjd  }|rN|
|||||d n|
||||d q|dkrXtd| td| td	| |d k	r|d k	rtd
t	|t
| |d k	r|d k	rtdt	|t
| |rt| t| tdD ]L}t| td}|r@|
|||||d n|
||||d q
d S )NOutputYop_typeenginerf   r*   )Zdevice_optionr-   r   Zquant_paramZX_quant_param r	   r   )rq   rr   rs   rf   )rq   rr   rs   )collections
namedtuplewsZcreate_blobfeedr   ZWorkspaceGuardr   ZCreateInt8QuantParamsBlobr$   r%   runr#   ZblobsfetchappendZFeedBlobZ
RunNetOnceZ	CreateNetZRunNetZ	FetchBlob)Z	test_caseZinit_netnetr*   r-   r   rr   rs   rf   gcr   ZscaleZ
zero_pointZx_scaleZx_zero_pointrp   r0   rq   r   r   r   run_conv_or_fcv  sj        
    



r~   )NFr   )FFF)FFF)NNNN)ru   Znumpyr   Zcaffe2.pythonr   r   Zcaffe2.quantization.serverr   Z
hypothesisr   r   r   r8   rU   rl   ro   r~   r   r   r   r   <module>   s,   

!w   
 *   
,    