U
    h%                     @   s   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 ddlmZ ddlmZ G dd	 d	eZG d
d deZG dd deZdS )    N)onnx_pb   )TENSOR_NAME_QUANT_SUFFIXQuantizedValueQuantizedValueTypeattribute_to_kwargfind_by_nameget_mul_node   )QuantOperatorBase)QDQOperatorBasec                       s,   e Zd Z fddZdd Zdd Z  ZS )ConvIntegerc                    s   t  || d S Nsuper__init__selfZonnx_quantizerZ	onnx_node	__class__ K/tmp/pip-unpacked-wheel-socb9apf/onnxruntime/quantization/operators/conv.pyr      s    zConvInteger.__init__c                 C   s   | j }| jj}t|jd | }|dkr@td|jd  d|jd }|jd }|d }|d }	tj	t
|jtjd	}
d
|
d< tj|tjjt
|jg|
}|| tjd||g|	g}|| tjd||	g|g|d }|| dS )a  
        Given a node, this function handles bias add by adding a "reshape" node on bias and an "add" node
            parameter nodes: new nodes would be appended into nodes
            parameter node: current node (Conv)
            parameter scaled_output: output of quant conv without bias
            parameter output: output of Conv
            parameter bias_name: bias of Conv
            return: the name of output
        r
   Nz	Expected z to be an initializerr   r   Z_bias_reshape_shapeZ_bias_reshape_output)ZdtypeZReshapeZAddZ	_bias_add)node	quantizermodelr   inputZinitializer
ValueErroroutputnpZoneslenZdimsZint64onnxhelperZmake_tensor
onnx_protoTensorProtoZINT64Zadd_initializer	make_nodeappend)r   nodesZscaled_outputr   r   Zweightr   Zreshape_input_dataZreshape_input_shapeZreshape_outputshapeZ
init_shapeZreshape_nodeadd_noder   r   r   add_bias   s,    


  
 

zConvInteger.add_biasc                 C   s  | j }|jdkst| j|dg\}}}}| jj|dg| jjd\}}}}	|| || || ||	 |jd d }
|j	r|j	d nd}i }|j
D ]}|t| qtjjd|| |
g|f|}|| |
d	 }tjjd
|
g|g|
d tjjd}|| t|dks t|r0|d }n|d d |d  d }t|| jj}|d krzt||d |}|| |jd }t|jdk}|s|jd n|jd d }|r|d nd}|t||g|| |r| || | j j|7  _d S )NConvr   r
   reduce_rangeZ_output_quantized_quant r   Z_cast_outputZCast_cast)tor   Z_scales_mul_Z_mulz:0   Zquant_scaled_outputZ_output_scale_mul)r   op_typeAssertionErrorr   quantize_activationquantize_weightr-   extendr   name	attributeupdater   r!   r"   r%   r&   r#   r$   FLOATr    r   	new_nodesr	   r   r*   )r   r   quantized_input_nameszero_point_namesscale_namesr'   quantized_input_names_weightzero_point_names_weightscale_names_weightnodes_weightZconv_integer_outputZconv_integer_namekwargsr:   Zconv_integer_nodeZcast_op_outputZ	cast_nodeZscales_mul_opZscales_mul_nodeZscales_mul_op_outputZhas_biasZscaled_output_nameZoutput_scale_mul_opr   r   r   quantize:   s~    




   





zConvInteger.quantize)__name__
__module____qualname__r   r*   rF   __classcell__r   r   r   r   r      s   %r   c                       s(   e Zd Z fddZ fddZ  ZS )QLinearConvc                    s   t  || d S r   r   r   r   r   r   r      s    zQLinearConv.__init__c                    s  | j }|jdkst| j|jd \}}}}}| j|jd r| j r| j	|dg\}}}}	| j
|jd tjjd}
||
d  ||
d  ||
d  n`| j	|dg\}}}}	| jj|dg| jjd\}}}}|| || || |	| |r|d kr$t  S d}d}t|jdkr|| jjtjjkrVtd	| j|jd |jd |jd }d
}|jd t }|jr|jd nd }}i }|jD ]}|t| qg }||d  ||d  ||d  ||d  ||d  ||d  || || |r@|| tjj d||g|f|}|	| t!|jd |||t"j#}|| jj$|jd < | j j%|	7  _%d S )Nr+   r   r
   r   r,   r/   Fr3   z@Quantization to FLOAT8E4M3FN for operator Conv is not supported.Tr.   rK   )&r   r4   r5   r   Z_get_quantization_paramsr   Zis_input_a_initializerr   is_per_channelr6   Zquantize_weight_per_channelr#   r$   ZINT8r&   r7   r-   r8   r   rF   r    Zweight_qTypeZFLOAT8E4M3FNRuntimeErrorZquantize_bias_staticr   r9   r:   r;   r   r!   r"   r%   r   r   ZInputZquantized_value_mapr=   )r   r   Z
data_foundZoutput_scale_nameZoutput_zp_namer2   r>   r?   r@   r'   Zquant_weight_tuplerA   rB   rC   rD   Zquantized_bias_nameZbias_presentZqlinear_conv_outputZqlinear_conv_namerE   r:   Zqlinear_conv_inputsZqlinear_conv_nodeZq_outputr   r   r   rF      s      




"



   
zQLinearConv.quantizerG   rH   rI   r   rF   rJ   r   r   r   r   rK      s   rK   c                       s$   e Zd Z fddZdd Z  ZS )QDQConvc                    s   t  || d S r   r   r   r   r   r   r      s    zQDQConv.__init__c                 C   s   | j }|jdks|jdkst| j|jd  | jsH| j|jd  | j rh| j	|jd d n| j
|jd  t|jdkr| j|jd |jd |jd  d S )Nr+   ZConvTransposer   r
   r3   r   )r   r4   r5   r   Zquantize_activation_tensorr   Zdisable_qdq_for_node_outputr   rL   Z"quantize_weight_tensor_per_channelZquantize_weight_tensorr    Zquantize_bias_tensor)r   r   r   r   r   rF      s    
zQDQConv.quantizerN   r   r   r   r   rO      s   rO   )Znumpyr   r!   r   r#   Zquant_utilsr   r   r   r   r   r	   Zbase_operatorr   Zqdq_base_operatorr   r   rK   rO   r   r   r   r   <module>   s    wd