o
    iz^                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZ d dlmZmZ d dlmZ eeZdd Zdd	d
ZdddZdd Zg dZdgddgddgdZG dd dZ									dddZdddZdS )    N)AttributeProto
GraphProto
ModelProto	NodeProtoTensorProtohelpernumpy_helper)infer_shapesinfer_shapes_path)versionc                 C   s   dd | D S )z|
    Convert numpy float16 to python int.

    :param np_list: numpy float16 list
    :return int_list: python int list
    c                 S   s.   g | ]}t t|d dd ddqS )H   N   )intbinviewzfill).0_ r   Z/home/kim/smarthome/.venv/lib/python3.10/site-packages/onnxruntime/transformers/float16.py
<listcomp>$   s   . z%_npfloat16_to_int.<locals>.<listcomp>r   )Znp_listr   r   r   _npfloat16_to_int   s   r   "\o>     @c                 C   s  dd }| t | dk jd dkrF| t | dk  }| t | dk  }||kr7td| d|  ||krFtd| d|  | t | dk  jd dkr| t | dk   }| t | dk   }|| kr{td| d|   || krtd| d|   t |d| ||| } t || | d| | } t ||| td|| } t |td| | | | } t | S )a?  
    Convert float32 numpy array to float16 without changing sign or finiteness.
    Positive values less than min_positive_val are mapped to min_positive_val.
    Positive finite values greater than max_finite_val are mapped to max_finite_val.
    Similar for negative values. NaN, 0, inf, and -inf are unchanged.
    c                 S   s   t | |k ||k S N)nplogical_and)abcr   r   r   between/   s   z&convert_np_to_float16.<locals>.betweenr   zthe float32 number z will be truncated to infz-inf)	r   whereshapemaxminloggerdebugfloatfloat16)Znp_arraymin_positive_valmax_finite_valr!   Zpositive_maxZpositive_minZnegative_maxZnegative_minr   r   r   convert_np_to_float16'   s(   


r-   c                 C   s   t | tstdt|  | jtjkrMtj| _| jr7tt	
| j||}t|}|| jdd< g | jdd< | jrMt	j| jdd}t|||}| | _| S )a  Convert tensor float to float16.

    Args:
        tensor (TensorProto): the tensor to convert.
        min_positive_val (float, optional): minimal positive value. Defaults to 1e-7.
        max_finite_val (float, optional): maximal finite value. Defaults to 1e4.

    Raises:
        ValueError: input type is not TensorProto.

    Returns:
        TensorProto: the converted tensor.
    3Expected input type is an ONNX TensorProto but got Nfloat32dtype)
isinstancer   
ValueErrortype	data_typeFLOATFLOAT16
float_datar-   r   arrayr   Z
int32_dataraw_data
frombuffertobytes)tensorr+   r,   float16_dataZint_listZfloat32_listZfloat16_listr   r   r   convert_tensor_float_to_float16I   s   

r?   c                 C   s   t | j}t| j| j|S r   )r   Zto_arrayr$   r   Zmake_tensor_value_infonamer5   )r=   r$   r   r   r   make_value_info_from_tensorn   s   rA   )ZArrayFeatureExtractorZ	BinarizerZCastMapZCategoryMapperZDictVectorizerZFeatureVectorizerZImputerZLabelEncoderZLinearClassifierZLinearRegressorZ
NormalizerZOneHotEncoderRandomUniformLikeZSVMClassifierZSVMRegressorZScalerZTreeEnsembleClassifierZTreeEnsembleRegressorZTreeEnsembleZZipMapZNonMaxSuppressionZTopKZRoiAlignRangeZCumSumZMinZMaxZUpsampler      )ZResizeZ	GroupNormZSkipGroupNormc                   @   s,   e Zd ZdZdefddZdefddZdS )	InitializerTrackerz'Class for keeping track of initializer.initializerc                 C   s   || _ g | _g | _d S r   )rF   
fp32_nodes
fp16_nodes)selfrF   r   r   r   __init__   s   
zInitializerTracker.__init__nodec                 C   s$   |r
| j | d S | j| d S r   )rG   appendrH   )rI   rK   is_node_blockedr   r   r   add_node   s   zInitializerTracker.add_nodeN)__name__
__module____qualname____doc__r   rJ   r   rN   r   r   r   r   rE      s    rE   Fc
           +         s	  |dksJ d|t ttjjksJ d|du ri n|}
t| trb| }tt	j
tdkr]|s]tjtj|d}|j}t|| t	|} d}W d   n1 sWw   Y  nt	|} t| tsptdt|  d}|stt	j
td	krzt}W nw |du rt}|du rg }t|}t|}td
| d| d  d| d| d| d|  g }g }g }g }|dur|| } ||  i }t }t }dd | jjD }dd | jjD }t tr fdd|D } fdd|D }n sg }g }t | jjD ]V\}}|j|v r\dt| }|||j< |!|j dt| }| jj"! }|#| ||_t$j%|jj&_'t(j)d|jg|gt$j%|dg}| jj*+| || |!| qt | jjD ]U\}}|j|v rdt| }|||j< |!|j dt| }| jj"! }|#| ||_t$j%|jj&_'t(j)d|g|jgd|dg}| jj*+| || |!| qdi }|rg } |D ]}!t|!tr| |!j t|!t,r|!j-D ]}|j.t$j/kr|j|vsJ t0|||j< q|!j*D ]}|j|v rqt1t2|jD ]}|j| |v r||j|  |j|< q	t1t2|jD ]}|j| |v r:||j|  |j|< q&|j3|v pF|j|v }"t |jD ](\}}||v rs|"pj|t45|j3g v oj||
5|j3g v}#|| 6||# qL|"r|| q|j3dkr|j7D ]}$|$jdkr|$j8t$j/krt$j%|$_8 nq|j3dv rd}%|j7D ]}$|$jd krd}%|$j8t$j/krt$j%|$_8q|j3d!v r|%s|j7+t(9d t$j%g |j3t4vs|j3|
v r|j7D ]}$| |$ qq|| qt|!t:r'| |!j; |!j<D ]}| | q|!j=#t>|!j=|| |!j?D ]	}t>|||}qt|!t,rzt@A|!j|!j|!j"D ]B}|jj&j't$j/krS|j|vrSt$j%|jj&_'|| |jBd"rx|jjCj'j&j't$j/krx|j|vrxt$j%|jjCj'j&_'|| q7q| }|s|D D ]*}&|s|&jErt>|&j-|||&_-|tF|&j- |&jGr|stHd#|&jE  q|D ]o}'t |'jD ]f\}}|t4|'j3 vs||
5|'j3g v rѐq|D ]J}(||(jkr| jj"! }|#|( |'jd$ t| }||_t$j/|jj&_'|'jd% t| }t(j)d|g|gd|dg}| jj*+| ||'j|<  nqӐqq|	r(t$jInt$j/})|D ]}'t1t2|'jD ]T}|'j| }|D ]I}(||(jkr| jj"! }|#|( |'jd$ t| }||_|)|jj&_'|'jd% t| }t(j)d|g|g|)|dg}| jj*+| ||'j|<  nq?q6t1t2|'jD ]T}|'j| }*|D ]I}(|*|(jkr| jj"! }|#|( |'jd& t| }||_|)|jj&_'|'jd' t| }t(j)d|g|*gd(|dg}| jj*+| ||'j|<  nqqq-| S ))a  Convert tensor float type in the input ONNX model to tensor float16.

    Args:
        model (ModelProto or str): The ONNX model or path of the model to convert.
        min_positive_val (float, optional): minimal positive value. Defaults to 5.96e-08.
        max_finite_val (float, optional): maximal finite value of float16. Defaults to 65504.
        keep_io_types (Union[bool, List[str]], optional): It could be boolean or a list of float32 input/output names.
                                                          If True, model inputs/outputs should be left as float32.
                                                          Defaults to False.
        disable_shape_infer (bool, optional): Skips running onnx shape/type inference.
                                              Useful if shape inference has been done. Defaults to False.
        op_block_list (List[str], optional): List of op types to leave as float32.
                                             Defaults to None, which will use `float16.DEFAULT_OP_BLOCK_LIST`.
        node_block_list (List[str], optional): List of node names to leave as float32. Defaults to None.
        force_fp16_initializers(bool): force converting all float initializers to float16.
                                       Default to false, which will convert only the one needed to avoid precision loss.
        force_fp16_inputs(Dict[str, List[int]]): Force the conversion of the inputs of some operators to float16, even if
                                                 this script's preference it to keep them in float32.
    Raises:
        ValueError: input type is not ModelProto.

    Returns:
        ModelProto: converted model.
    r   zginvalid min_positive_val. smallest positive float16 value: subnormal 5.96e-08, and normalized 6.104e-05z4invalid max_finite_val. largest float16 value: 65504Nz1.8.0)dirTz$Expected an ONNX ModelProto but got z1.2.0z"fp16 parameters: min_positive_val=z max_finite_val=z keep_io_types=z disable_shape_infer=z op_block_list=z node_block_list=z force_fp16_initializers=c                 S   "   g | ]}|j jjtjkr|jqS r   r4   tensor_type	elem_typer   r6   r@   r   nr   r   r   r        " z,convert_float_to_float16.<locals>.<listcomp>c                 S   rT   r   rU   rX   r   r   r   r     rZ   c                       g | ]}| v r|qS r   r   rX   keep_io_typesr   r   r   
      c                    r[   r   r   rX   r\   r   r   r     r^   Zgraph_input_cast_Zgraph_input_castZCast)tor@   Zgraph_output_cast_Zgraph_output_castrD   r_   )ZEyeLikeZMultinomialRandomNormalZRandomNormalLikeRandomUniformrB   SequenceEmptyZ	BernoulliFr1   )r`   ra   rb   sequence_typezXinitializer is used by both fp32 and fp16 nodes. Consider add these nodes to block list:Z_input_cast_Z_input_castZ_output_cast_Z_output_cast
   )Jr)   r   Zfinfor*   r%   r2   strr   parseonnx__version__tempfileNamedTemporaryFileospathdirnamer@   r
   loadr   r3   r4   r	   DEFAULT_OP_BLOCK_LISTsetr'   r(   rL   graphinputoutputlist	enumerateadd
value_infoZCopyFromr   r7   rV   rW   r   Z	make_noderK   extendr   rF   r5   r6   rE   rangelenZop_typeALWAYS_FLOAT_INPUTSgetrN   	attributeiZmake_attributer   gZgraphstr?   Ztensors	itertoolschainZHasFieldrc   valuesrH   rA   rG   infoZBFLOAT16)+modelr+   r,   r]   Zdisable_shape_inferZop_block_listZnode_block_listZforce_fp16_initializersZforce_fp16_inputsZ#use_bfloat16_as_blocked_nodes_dtypeZforce_fp16_inputs_dictZ
model_pathZtmpfileZshape_infer_model_pathZfunc_infer_shapequeueZvalue_info_listZ	node_listZmixed_float_type_node_listZname_mappingZgraph_io_to_skipZio_castsZfp32_inputsZfp32_outputsr~   rY   Zoutput_nameZ	node_nameZnew_value_infonew_nodeZ
input_nameZfp32_initializersZ
next_levelqrM   Zuse_fp32_weightattrZ	has_dtypevaluerK   rw   Zaccuracy_typers   r   r\   r   convert_float_to_float16   s  
$




,





















d
$









r   c                 C   s   t | tstdt|  | jtjkrtdd}| jr#t| j}| j	r.tj
| j	dd}|du r6tdt|||}tt|t| S )zSMeasure the maximum absolute difference after converting a float tensor to float16.r.   z#Expected tensor data type is float.Nr/   r0   zexternal data not loaded!)r2   r   r3   r4   r5   r6   r8   r   r9   r:   r;   RuntimeErrorr-   Zamaxabsr/   )r=   r+   r,   Zfloat32_datar>   r   r   r   float_to_float16_max_diff  s   
r   )r   r   )	r   r   FFNNFNF)r   loggingrk   ri   numpyr   rg   r   r   r   r   r   r   r   Zonnx.shape_inferencer	   r
   	packagingr   	getLoggerrO   r'   r   r-   r?   rA   ro   r{   rE   r   r   r   r   r   r   <module>   s<   $



"%"
  >