o
    3Ihz^                     @   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   `/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/onnxruntime/transformers/float16.py
<listcomp>$   s   . z%_npfloat16_to_int.<locals>.<listcomp>r   )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)np_arraymin_positive_valmax_finite_valr"   positive_maxpositive_minnegative_maxnegative_minr   r   r   convert_np_to_float16'   s(   


r3   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_datar3   r   arrayr   
int32_dataraw_data
frombuffertobytes)tensorr-   r.   float16_dataint_listfloat32_listfloat16_listr   r   r   convert_tensor_float_to_float16I   s   

rI   c                 C   s   t | j}t| j| j|S r   )r   to_arrayr%   r   make_tensor_value_infonamer;   )rD   r%   r   r   r   make_value_info_from_tensorn   s   rM   )ArrayFeatureExtractor	BinarizerCastMapCategoryMapperDictVectorizerFeatureVectorizerImputerLabelEncoderLinearClassifierLinearRegressor
NormalizerOneHotEncoderRandomUniformLikeSVMClassifierSVMRegressorScalerTreeEnsembleClassifierTreeEnsembleRegressorTreeEnsembleZipMapNonMaxSuppressionTopKRoiAlignRangeCumSumMinMaxUpsampler      )Resize	GroupNorm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   )ro   
fp32_nodes
fp16_nodes)selfro   r   r   r   __init__   s   
zInitializerTracker.__init__nodec                 C   s$   |r
| j | d S | j| d S r   )rp   appendrq   )rr   rt   is_node_blockedr   r   r   add_node   s   zInitializerTracker.add_nodeN)__name__
__module____qualname____doc__r   rs   r   rw   r   r   r   r   rn      s    rn   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   r:   tensor_type	elem_typer   r<   rL   r   nr   r   r   r        " z,convert_float_to_float16.<locals>.<listcomp>c                 S   r}   r   r~   r   r   r   r   r     r   c                       g | ]}| v r|qS r   r   r   keep_io_typesr   r   r   
      c                    r   r   r   r   r   r   r   r     r   graph_input_cast_graph_input_castCast)torL   graph_output_cast_graph_output_castrj   r   )EyeLikeMultinomialRandomNormalRandomNormalLikeRandomUniformrZ   SequenceEmpty	BernoulliFr7   )r   r   r   sequence_typezXinitializer is used by both fp32 and fp16 nodes. Consider add these nodes to block list:_input_cast__input_cast_output_cast__output_cast
   )Jr*   r   finfor+   r&   r8   strr   parseonnx__version__tempfileNamedTemporaryFileospathdirnamerL   r
   loadr   r9   r:   r	   DEFAULT_OP_BLOCK_LISTsetr(   r)   ru   graphinputoutputlist	enumerateadd
value_infoCopyFromr   r=   r   r   r   	make_nodert   extendr   ro   r;   r<   rn   rangelenop_typeALWAYS_FLOAT_INPUTSgetrw   	attributeimake_attributer   ggraphstrI   tensors	itertoolschainHasFieldr   valuesrq   rM   rp   infoBFLOAT16)+modelr-   r.   r   disable_shape_inferop_block_listnode_block_listforce_fp16_initializersforce_fp16_inputs#use_bfloat16_as_blocked_nodes_dtypeforce_fp16_inputs_dict
model_pathtmpfileshape_infer_model_pathfunc_infer_shapequeuevalue_info_list	node_listmixed_float_type_node_listname_mappinggraph_io_to_skipio_castsfp32_inputsfp32_outputsr   r   output_name	node_namenew_value_infonew_node
input_namefp32_initializers
next_levelqrv   use_fp32_weightattr	has_dtypevaluert   r   accuracy_typer   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.r4   z#Expected tensor data type is float.Nr5   r6   zexternal data not loaded!)r8   r   r9   r:   r;   r<   r>   r   r?   rA   rB   RuntimeErrorr3   amaxabsr5   )rD   r-   r.   float32_datarE   r   r   r   float_to_float16_max_diff  s   
r   )r   r   )	r   r   FFNNFNF)r   loggingr   r   numpyr   r   r   r   r   r   r   r   r   onnx.shape_inferencer	   r
   	packagingr   	getLoggerrx   r(   r   r3   rI   rM   r   r   rn   r   r   r   r   r   r   <module>   s<   $



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