o
    gQ                     @  sr   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 eG dd	 d	ZG d
d deZdS )    )annotationsN)MutableMapping)	dataclass)Any   )	QuantTypec                   @  sh   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Ze				ddddZ
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otherobjectc                 C  sf   t |tr1| j|jko0| jd u p|jd u p| j|jko0| jd u p*|jd u p*| j|jko0| j|jkS tS N)
isinstancer   r	   r   r   r   NotImplemented)selfr    r   f/var/www/visachat/venv/lib/python3.10/site-packages/onnxruntime/quantization/tensor_quant_overrides.py__eq__   s   

zQuantTypeInfo.__eq__raw_dictdict[str, Any]default_qtypeQuantType | None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_dictc                 C  sN   | j |d< | jd ur| j|d< | jd ur| j|d< | jd ur%| j|d< d S d S r   )r	   r   r   r   )r   r   r   r   r   save_to_dict5   s   





zQuantTypeInfo.save_to_dict)r   r   )NNN)
r   r   r   r   r   r
   r   r
   r   r   )r   r   )__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dUddZdVd
dZdVddZdVddZ	dWdXddZ	dWdYddZ	dZddZ
d[ddZd\d"d#Zd]d(d)Z		*d^d_d/d0Z	dWd`d7d8Z		dadbd<d=ZdWdcd>d?Zddd@dAZdedBdCZdfdGdHZdgdIdJZdhdKdLZdMdN ZdOdP ZdcdQdRZdc fdSdTZ  ZS )iTensorQuantOverridesHelperzZ
    Utility wrapper over the tensor quantization overrides passed via extra_options.
    raw_overridesdict[str, list[dict[str, Any]]]c                 C  s   || _ d | _h d| _d S )N>   rmaxrminr   r   )	overridesquant_typeskeys_unsupported_with_scale_zp)r   r)   r   r   r   __init__D   s   z#TensorQuantOverridesHelper.__init__tensor_namestrr   boolc                 C  s   | j |}|od|d vS Nr   r   r-   r   r   r1   overrides_listr   r   r   has_per_tensor_overridesI      z3TensorQuantOverridesHelper.has_per_tensor_overridesc                 C  s   | j |}|od|d v S r4   r5   r6   r   r   r   has_per_channel_overridesM   r9   z4TensorQuantOverridesHelper.has_per_channel_overridesc                 C  s(   | j |}|od|d v od|d v S )Nscaler   
zero_pointr5   r6   r   r   r   overrides_scale_zpQ   s   z-TensorQuantOverridesHelper.overrides_scale_zpNdefault_valdict[str, Any] | Nonec                 C  sP   |d ur|gnd }| j ||}|r d|d v r td| d|r&|d S d S )Nr   r   Expected tensor 'zL' to use per-tensor quantization overrides, but found per-channel overrides.r-   r   
ValueError)r   r1   r>   default_list_valr7   r   r   r   get_per_tensor_overridesU   s   
z3TensorQuantOverridesHelper.get_per_tensor_overrideslist[dict[str, Any]] | Nonec                 C  s6   | j ||}|sd S d|d vrtd| d|S )Nr   r   r@   zE' to have per-channel quantization overrides (axis value is missing).rA   )r   r1   r>   r7   r   r   r   get_per_channel_overridesd   s   
z4TensorQuantOverridesHelper.get_per_channel_overridesset[QuantType]c                 C  s~   | j d ur| j S t | _ | jr<| j D ]'}|D ]"}d|v r&| j |d  d|v r:d|d v r:| j |d d  qq| j S )Nr	   convert)r.   setr-   valuesadd)r   quant_overrides_listquant_overridesr   r   r   get_quant_typesu   s   
z*TensorQuantOverridesHelper.get_quant_typesrM   r   tuple[bool, str | None]c                 C  s  t |tsdd| dfS ||v }|d}|r| j| d|v }d|v }|r*|r.|r0|s0dS |rG| jt|}	|	rGddd	|	 d
fS d|v rT|sTdd| fS d|v r|r\dS d|d vrjdd| dfS d|d v rwdd| fS |d d }
|d ur|n|}|
|krdd| dfS d|d v }d|d v }|r|r|r|sd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	   r;   r<   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 rH   )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.   rK   r/   intersectionrI   join)r   initializersdefault_activation_qtyper1   rM   is_initializerr	   	has_scalehas_zero_pointkeysconvert_quant_typeoriginal_quant_typeconvert_has_scaleconvert_has_zero_pointr   r   r   _is_valid_per_tensor   sj   




z/TensorQuantOverridesHelper._is_valid_per_tensorrL   list[dict[str, Any]]c              
   C  s^  ||v }|sdd| dfS |d  d}|d u r!dd| dfS t|| j}t|}|}|dk r6||7 }|dk s@|t|krMdd| d	t| d
fS t|dkrpt||| krpdd| d| d||  dt| d	fS d|d v r~dd| dfS |d  d}	|	r| j|	 |d  d}
|d  d}d|d v }d|d v }|o|}|r|r|r|sdS |r| jt|d }|rddd	| dfS d|d v }d|d v }|o|}|r|r|s|rdS t
|dd  D ]\}}t|tsdd| d | d!f  S d|v rdd| df  S d|v r%|	|d kr% d"S d|v r;||d kr;||d kr; d#S d|v rJ|
|d krJ d$S d|v rY||d krY d%S d|v oad|v }|ru|sudd&| d'| df  S |r| jt|}|rddd	| df  S d|v od|v }|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 .rH   z8Cannot use 'convert' override for initializers, such as r	   r   r   r;   r<   rR   rS   rT   rU   r,   r+   )Fz6Must provide both 'rmin' and 'rmax' if one is providedz'Tensor quantization overrides at index z for 'rQ   )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 'rV   )r   listdimslenr.   rK   r/   rX   rI   rY   	enumerater   rW   )r   rZ   r1   rL   r\   r   weight_shapeweight_rank	norm_axisr	   r   r   r]   r^   has_scale_zpr_   has_rminhas_rmaxhas_rmin_rmaxindexrM   chan_has_scale_zpchan_has_rmin_rmaxr   r   r   _is_valid_per_channel   s   


&z0TensorQuantOverridesHelper._is_valid_per_channelrZ   dict[str, onnx.TensorProto]activation_namesset[str]c                 C  s   t  | _| jrr| j D ]e\}}||vr"||vr"dd| df  S t|ts1dd| df  S |s4qt|d tsEdd| df  S |d sJq|d d	}t|d
kpZ|d u}|rf| 	|||  S | 
||||d   S dS )NFrf   z5' in TensorQuantOverrides is not present in the modelrP   z' are not in a listr   z.Tensor quantization overrides at index 0 for 'rQ   r   r   rV   )rI   r.   r-   itemsr   ri   rW   r   rk   rw   rd   )r   rZ   ry   r[   r1   rL   r   is_per_channelr   r   r   is_validi  s*   
z#TensorQuantOverridesHelper.is_validTnew_valschannelslist[int] | None	overwritec           	      C  s   |sdS |d urt |nd }| j|}d}|s<|r<t| j| D ]\}}|d ur.||vr.q!t |t |r;d} nq!|r`|sFi g| j|< t| j| D ]\}}|d urZ||vrZqM|| qM|S )NFT)rI   r-   r   rl   rX   update)	r   r1   r~   r   r   have_overrides	do_updatechannelr-   r   r   r   update_tensor_overrides  s*   z2TensorQuantOverridesHelper.update_tensor_overridesoutput_namer   r   r   r
   r   c                 C  s<   || j vr
t||S | j | d }t|d||d|S )Nr   r	   r   )r-   r   r   )r   r   r   r   tensor_overridesr   r   r   get_node_output_qtype_info  s   



z5TensorQuantOverridesHelper.get_node_output_qtype_info
input_name	node_namer   c           
      C  s   || j vs
| j | st|||S | j | d }|d|}d|vr3t||d||d||dS |d }t||d|}	d|vsJ||d v rO|d |	_|	S )Nr   r	   rH   r   r   r   
recv_nodes)r-   r   r   r	   )
r   r   r   r   r   r   r   producer_typeconvert_dict
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-   r2   )r   r   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   r   r   r   r   r   get_dict  s   z#TensorQuantOverridesHelper.get_dictkeyvalue
list[dict]c                 C  s   || j |< d S r   r   )r   r   r   r   r   r   __setitem__  s   z&TensorQuantOverridesHelper.__setitem__c                 C  s
   | j | S r   r   r   r   r   r   r   __getitem__     
z&TensorQuantOverridesHelper.__getitem__c                 C  s   | j |= d S r   r   r   r   r   r   __delitem__  s   z&TensorQuantOverridesHelper.__delitem__c                 C  
   t | jS r   )iterr-   r   r   r   r   __iter__  r   z#TensorQuantOverridesHelper.__iter__c                 C  r   r   )rk   r-   r   r   r   r   __len__  r   z"TensorQuantOverridesHelper.__len__c                 C  r   r   )r2   r-   r   r   r   r   __str__  r   z"TensorQuantOverridesHelper.__str__c                   s   t    d| j dS )Nz, TensorQuantOverridesHelper(rg   )super__repr__r-   r   	__class__r   r   r     s   z#TensorQuantOverridesHelper.__repr__)r)   r*   )r1   r2   r   r3   r   )r1   r2   r>   r?   r   r?   )r1   r2   r>   rE   r   rE   )r   rG   )r1   r2   rM   r   r   rO   )r1   r2   rL   re   r   rO   )rZ   rx   ry   rz   r   rO   )NT)
r1   r2   r~   r   r   r   r   r3   r   r3   )r   r2   r   r   r   r
   r   r   )NN)r   r2   r   r2   r   r   r   r
   r   r
   r   r   )r   r2   )r   r3   )r   r*   )r   r2   r   r   )r   r2   r   r   )r   r2   )r"   r#   r$   r%   r0   r8   r:   r=   rD   rF   rN   rd   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r(   ?   sB    






U 
*''





r(   )
__future__r   r   collections.abcr   dataclassesr   typingr   onnxquant_utilsr   r   r(   r   r   r   r   <module>   s   ,