U
    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__ Y/var/www/html/venv/lib/python3.8/site-packages/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Reshape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   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|}|| | jj|jd d	d
}|
d }tjjd|
g|g|
d |d}|| t|dks2t|rB|d }n|d d |d  d }t|| jj}|d krt||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   T)	mandatoryZ_cast_outputZCastZ_cast)tor   Z_scales_mul__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'   Zget_tensor_typer!   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	onnx_typeZ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,   rH   __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.   r1   Fr6   z@Quantization to FLOAT8E4M3FN for operator Conv is not supported.Tr0   rM   )&r   r7   r8   r   Z_get_quantization_paramsr   Zis_input_a_initializerr   Zis_per_channelr9   Zquantize_weight_per_channelr$   r%   ZINT8r'   r:   r/   r;   r   rH   r!   Zweight_qTypeZFLOAT8E4M3FNRuntimeErrorZquantize_bias_staticr   r<   r=   r>   r   r"   r#   r&   r   r   ZInputZquantized_value_mapr?   )r   r   Z
data_foundZoutput_scale_nameZoutput_zp_namer4   r@   rA   rB   r(   Zquant_weight_tuplerC   rD   rE   rF   Zquantized_bias_nameZbias_presentZqlinear_conv_outputZqlinear_conv_namerG   r=   Zqlinear_conv_inputsZqlinear_conv_nodeZq_outputr   r   r   rH      s      




"



   
zQLinearConv.quantizerI   rJ   rK   r   rH   rL   r   r   r   r   rM      s   rM   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j|jd |jdkrddndd\}}|r| j	|jd | n| j
|jd  t|jdkr| j|j|jd |jd |jd  d S )Nr-   ZConvTransposer   r
   )Zdefault_axisr6   r   )r   r7   r8   r   Zquantize_activation_tensorr   Zdisable_qdq_for_node_outputr   Zis_tensor_per_channelZ"quantize_weight_tensor_per_channelZquantize_weight_tensorr!   Zquantize_bias_tensorr<   )r   r   Zis_weight_per_channelZweight_axisr   r   r   rH      s     
zQDQConv.quantizerO   r   r   r   r   rP      s   rP   )numpyr    r"   r   r$   Zquant_utilsr   r   r   r   r   r	   Zbase_operatorr   Zqdq_base_operatorr   r   rM   rP   r   r   r   r   <module>   s    xd