U
    U?hiP                     @  sv   d dl mZ d dlZd dlmZ d dlmZ d dlmZ d dl	Z	ddl
mZmZ eG dd	 d	ZG d
d deZdS )    )annotationsN)MutableMapping)	dataclass)Any   )	QuantTypetensor_proto_to_arrayc                   @  sv   e Zd ZU dZded< dZded< dZded< dZded	< d
dddZe	dddddd dddZ
ddddZdS )QuantTypeInfozB
    The quantization type information for a tensor override.
    r   
quant_typeNbool | None	symmetricreduce_rangez
int | Noneaxisobject)otherc                 C  sf   t |trb| j|jko`| jd ks6|jd ks6| j|jko`| jd ksV|jd ksV| j|jko`| j|jkS tS N)
isinstancer	   r
   r   r   r   NotImplemented)selfr    r   a/var/www/html/venv/lib/python3.8/site-packages/onnxruntime/quantization/tensor_quant_overrides.py__eq__   s    

zQuantTypeInfo.__eq__dict[str, Any]QuantType | None)raw_dictdefault_qtypedefault_symmetricdefault_reduce_rangereturnc                 C  s,   t | d|| d|| d|| dS Nr
   r   r   r   )r	   get)r   r   r   r   r   r   r   load_from_dict'   s    


zQuantTypeInfo.load_from_dict)r   c                 C  sJ   | j |d< | jd k	r| j|d< | jd k	r2| j|d< | jd k	rF| j|d< d S r   )r
   r   r   r   )r   r   r   r   r   save_to_dict5   s    





zQuantTypeInfo.save_to_dict)NNN)__name__
__module____qualname____doc____annotations__r   r   r   r   staticmethodr!   r"   r   r   r   r   r	      s   

   r	   c                      s  e Zd ZdZddddZdddd	d
ZdddddZdMddddddZdNddddddZddddZ	ddddddZ
ddddd d!Zd"d#dd$d%d&ZdOddd(ddd)d*d+ZdPdd,d-d.d/d0d1ZdQddd,d-d-d.d2d3d4ZdRddd5d6Zddd7d8Zddd9d:Zdd;d<d=d>Zdd;d?d@dAZddBdCdDZdEdF ZdGdH ZdddIdJZdd fdKdLZ  ZS )STensorQuantOverridesHelperzZ
    Utility wrapper over the tensor quantization overrides passed via extra_options.
    zdict[str, list[dict[str, Any]]])raw_overridesc                 C  s   || _ d | _ddddh| _d S )Nr   r   rmaxrmin)	overridesquant_typeskeys_unsupported_with_scale_zp)r   r*   r   r   r   __init__D   s    z#TensorQuantOverridesHelper.__init__strbool)tensor_namer   c                 C  s   | j |}|od|d kS Nr   r   r-   r    r   r3   overrides_listr   r   r   has_per_tensor_overridesI   s    z3TensorQuantOverridesHelper.has_per_tensor_overridesc                 C  s   | j |}|od|d kS r4   r5   r6   r   r   r   has_per_channel_overridesM   s    z4TensorQuantOverridesHelper.has_per_channel_overridesNzdict[str, Any] | None)r3   default_valr   c                 C  sP   |d k	r|gnd }| j ||}|r@d|d kr@td| d|rL|d S d S )Nr   r   Expected tensor 'zL' to use per-tensor quantization overrides, but found per-channel overrides.r-   r    
ValueError)r   r3   r:   Zdefault_list_valr7   r   r   r   get_per_tensor_overridesQ   s    
z3TensorQuantOverridesHelper.get_per_tensor_overrideszlist[dict[str, Any]] | Nonec                 C  s6   | j ||}|sd S d|d kr2td| d|S )Nr   r   r;   zE' to have per-channel quantization overrides (axis value is missing).r<   )r   r3   r:   r7   r   r   r   get_per_channel_overrides`   s    
z4TensorQuantOverridesHelper.get_per_channel_overrideszset[QuantType])r   c                 C  s~   | j d k	r| j S t | _ | jrx| j D ]N}|D ]D}d|krL| j |d  d|kr0d|d kr0| j |d d  q0q(| j S )Nr
   convert)r.   setr-   valuesadd)r   quant_overrides_listquant_overridesr   r   r   get_quant_typesq   s    
z*TensorQuantOverridesHelper.get_quant_typesr   ztuple[bool, str | None])r3   rE   r   c                 C  s  t |tsdd| dfS ||k}|d}|r<| j| d|k}d|k}|rT|r\|r`|s`dS |r| jt|}	|	rddd	|	 d
fS d|kr|sdd| fS d|kr|rdS d|d krdd| dfS d|d krdd| fS |d d }
|d k	r
|n|}|
|kr(dd| dfS d|d k}d|d k}|rL|rX|rh|shdd| dfS |r| jt|d }	|	rddd	|	 d| dfS | j|
 dS )NF#Tensor quantization overrides for '' are not in a dictr
   scale
zero_pointFzNMust provide both 'scale' and 'zero_point' if one of the overrides is providedTensor override option(s) [, +] are invalid with 'scale' and 'zero_point'r   zMOption 'reduce_range' is only supported for initializers, not for activation r@   )Fz.Cannot use 'convert' override for initializersz'convert' options (tensor 'z') must specify a 'quant_type'zC'convert' quant_type must differ from original quant_type (tensor 'z')zXMust provide both 'scale' and 'zero_point' if one of the overrides is provided (tensor 'z5] are invalid with 'scale' and 'zero_point' (tensor 'TN)	r   dictr    r.   rC   r/   intersectionrA   join)r   initializersdefault_activation_qtyper3   rE   is_initializerr
   	has_scalehas_zero_pointkeysZconvert_quant_typeZoriginal_quant_typeZconvert_has_scaleZconvert_has_zero_pointr   r   r   _is_valid_per_tensor   sf    






z/TensorQuantOverridesHelper._is_valid_per_tensorzlist[dict[str, Any]])r3   rD   r   c              
   C  s|  ||k}|sdd| dfS |d  d}|d krBdd| dfS t|| j}t|}|}|dk rl||7 }|dk s|t|krdd| d	t| d
fS t|dkrt||| krdd| d| d||  dt| d	fS d|d krdd| dfS |d  d}	|	r| j|	 |d  d}
|d  d}d|d k}d|d k}|oX|}|rf|rr|rv|svdS |r| jt|d }|rddd	| dfS d|d k}d|d k}|o|}|r|r|s|rdS t
|dd  D ]z\}}t|ts*dd| d | d!f  S d|krHdd| df  S d|krf|	|d krf d"S d|kr||d kr||d kr d#S d|kr|
|d kr d$S d|kr||d kr d%S d|kod|k}|r|sdd&| d'| df  S |r<| jt|}|r<ddd	| df  S d|koLd|k}|r|sdd(| d'| df  S qd)S )*NFTensor 'z6' has per-channel overrides, but is not an initializerr   r   z!Per-channel overrides for tensor z< is missing an 'axis' value in the first channel dictionary.z0Axis override value is out-of-bounds for tensor z (rank )r   z1Incorrect number of channel overrides for tensor z (axis z), expected z, but found .r@   z8Cannot use 'convert' override for initializers, such as r
   r   r   rI   rJ   rK   rL   rM   rN   r,   r+   )Fz6Must provide both 'rmin' and 'rmax' if one is providedz'Tensor quantization overrides at index z for 'rH   )FzTChannel quantization types for tensor '{tensor_name}' do not match at index {index}.)FzHChannel axis for tensor '{tensor_name}' does not match at index {index}.)FzSChannel symmetric value for tensor '{tensor_name}' does not match at index {index}.)FzVChannel reduce_range value for tensor '{tensor_name}' does not match at index {index}.z]Per-channel overrides that specify scale/zero_point must do so for all channels, but tensor 'z' is missing them at index zVPer-channel overrides that specify rmin/rmax must do so for all channels, but tensor 'rO   )r    r   shapelenr.   rC   r/   rQ   rA   rR   	enumerater   rP   )r   rS   r3   rD   rU   r   Zweight_shapeZweight_rankZ	norm_axisr
   r   r   rV   rW   Zhas_scale_zprX   Zhas_rminZhas_rmaxZhas_rmin_rmaxindexrE   Zchan_has_scale_zpZchan_has_rmin_rmaxr   r   r   _is_valid_per_channel   s    

$


&z0TensorQuantOverridesHelper._is_valid_per_channelzdict[str, onnx.TensorProto]zset[str])rS   activation_namesr   c                 C  s   t  | _| jr| j D ]\}}||krD||krDdd| df  S t|tsbdd| df  S |shqt|d tsdd| df  S |d sq|d d	}t|d
kp|d k	}|r| 	|||  S | 
||||d   S dS )NFrZ   z5' in TensorQuantOverrides is not present in the modelrG   z' are not in a listr   z.Tensor quantization overrides at index 0 for 'rH   r   r   rO   )rA   r.   r-   itemsr   listrP   r    r^   ra   rY   )r   rS   rb   rT   r3   rD   r   Zis_per_channelr   r   r   is_valide  s0    
   z#TensorQuantOverridesHelper.is_validTzlist[int] | None)r3   new_valschannels	overwriter   c           	      C  s   |sdS |d k	rt |nd }| j|}d}|sx|rxt| j| D ]4\}}|d k	r\||kr\qBt |t |rBd} qxqB|r|si g| j|< t| j| D ]$\}}|d k	r||krq|| q|S )NFT)rA   r-   r    r_   rQ   update)	r   r3   rf   rg   rh   Zhave_overridesZ	do_updateZchannelr-   r   r   r   update_tensor_overrides  s(    z2TensorQuantOverridesHelper.update_tensor_overridesr   r   r	   )output_namer   r   r   c                 C  s<   || j krt||S | j | d }t|d||d|S )Nr   r
   r   )r-   r	   r    )r   rk   r   r   tensor_overridesr   r   r   get_node_output_qtype_info  s    



z5TensorQuantOverridesHelper.get_node_output_qtype_info)
input_name	node_namer   r   r   r   c           
      C  s   || j ks| j | s t|||S | j | d }|d|}d|krft||d||d||dS |d }t||d|}	d|ks||d kr|d |	_|	S )Nr   r
   r@   r   r   r   Z
recv_nodes)r-   r	   r    r
   )
r   rn   ro   r   r   r   rl   Zproducer_typeZconvert_dictZ
qtype_infor   r   r   get_node_input_qtype_info  s&    



z4TensorQuantOverridesHelper.get_node_input_qtype_infoc                 C  s   t j| jt|dS )N)defaultindent)jsondumpsr-   r1   )r   rr   r   r   r   
pprint_str  s    z%TensorQuantOverridesHelper.pprint_strc                 C  s   | j  S r   r-   r   r   r   r   empty  s    z TensorQuantOverridesHelper.emptyc                 C  s   | j S r   rv   rw   r   r   r   get_dict  s    z#TensorQuantOverridesHelper.get_dictz
list[dict])keyvaluec                 C  s   || j |< d S r   rv   )r   rz   r{   r   r   r   __setitem__  s    z&TensorQuantOverridesHelper.__setitem__)rz   r   c                 C  s
   | j | S r   rv   r   rz   r   r   r   __getitem__  s    z&TensorQuantOverridesHelper.__getitem__)rz   c                 C  s   | j |= d S r   rv   r}   r   r   r   __delitem__  s    z&TensorQuantOverridesHelper.__delitem__c                 C  s
   t | jS r   )iterr-   rw   r   r   r   __iter__  s    z#TensorQuantOverridesHelper.__iter__c                 C  s
   t | jS r   )r^   r-   rw   r   r   r   __len__  s    z"TensorQuantOverridesHelper.__len__c                 C  s
   t | jS r   )r1   r-   rw   r   r   r   __str__   s    z"TensorQuantOverridesHelper.__str__c                   s   t    d| j dS )Nz, TensorQuantOverridesHelper(r[   )super__repr__r-   rw   	__class__r   r   r     s    z#TensorQuantOverridesHelper.__repr__)N)N)NT)N)NN)N)r#   r$   r%   r&   r0   r8   r9   r>   r?   rF   rY   ra   re   rj   rm   rp   ru   rx   ry   r|   r~   r   r   r   r   r   __classcell__r   r   r   r   r)   ?   s>     U *  '   'r)   )
__future__r   rs   collections.abcr   dataclassesr   typingr   ZonnxZquant_utilsr   r   r	   r)   r   r   r   r   <module>   s   ,