o
    wiu                     @  s  d dl mZ d dlZd dlmZmZ d dlZd dlm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mZ erFd dlmZ dmddZe
jded	dndoddZdpddZejeddgdZ e
jded			 dqdrd!d"Z!dpd#d$Z"eje"ddgdZ#e
jded		 	 dsdrd%d&Z$e
jd'eddtd+d,Z%dud0d1Z&dvd2d3Z'dwd4d5Z(dxd7d8Z)dyd9d:Z*dzd{d@dAZ+dnd|dEdFZ,dnd}dGdHZ-d~dLdMZ.	dddQdRZ/ddVdWZ0dnddYdZZ1dd^d_Z2	dddadbZ3ddddeZ4	fdddkdlZ5dS )    )annotationsN)TYPE_CHECKINGAny)MapProtoOptionalProtoSequenceProtoTensorProtohelpersubbyte)load_external_data_for_tensoruses_external_data)SequencefaSequence[int]returnlist[complex]c                   s    fddt t d D S )Nc                   s*   g | ]}t  |d    |d  d  qS )      )complex).0ir    N/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/onnx/numpy_helper.py
<listcomp>   s   * z-_combine_pairs_to_complex.<locals>.<listcomp>r   )rangelenr   r   r   r   _combine_pairs_to_complex   s   r   zpDeprecated since 1.18. Scheduled to remove in 1.20. Consider using libraries like ml_dtypes for dtype conversion)categorydata np.int16 | np.int32 | np.ndarraydimsint | Sequence[int] | None
np.ndarrayc                 C  sx   dd }|du r-t | jdkr!|t| gtjtjd S || tjtjS || tj|tjS )a_  Converts ndarray of bf16 (as uint32) to f32 (as uint32).

    Args:
        data: A numpy array, empty dimensions are allowed if dims is
            None.
        dims: If specified, the function reshapes the results.

    Returns:
        A numpy array of float32 with the same dimension if dims is
        None, or reshaped to dims if specified
    c                 S  s   | d> S )N   r   xr   r   r   <lambda>,   s    z%bfloat16_to_float32.<locals>.<lambda>Nr   )	r   shapenparrayastypeint32viewfloat32reshape)r   r!   shiftr   r   r   bfloat16_to_float32   s   $r1   ivalintfnbooluz
np.float32c           	      C  sV  |st d| dk s| dkrt|  d|r!d}| dkr tjS nd}| dkr.ttj S | dkr8ttjS t| } | d	@ d
? }| d@ }| d@ }|d> }|dkr|dkrd| }|d@ dkrm|d
M }|dK }|d8 }|d@ dkr|d
M }|dK }|d8 }||d
@ d> O }||d> O }n||d> O }|d| 7 }||d> O }t|tj}|S )Nzfn=False is not implemented.r      z is not a float8.            x            r            )NotImplementedError
ValueErrorr)   nanr.   uint32r-   	r2   r4   r6   exponent_biasexpomantsignresfr   r   r   _float8e4m3_to_float32_scalar4   sL   
rO   )excludedTFc                 C  s0   |st dt| ||d}|du r|S ||S )a  Converts ndarray of float8, e4m3 (as uint32) to f32 (as uint32).

    See :ref:`onnx-detail-float8` for technical details.

    Args:
        data: A numpy array, empty dimensions are allowed if dims is None.
        dims: If specified, the function reshapes the results.
        fn: No infinite values.
        uz: No negative zero.

    Returns:
        A numpy array of float32 with the same dimension if dims is None,
        or reshaped to dims if specified.
    z4float32_to_float8e4m3 not implemented with fn=False.r4   r6   N)rD   _float8e4m3_to_float32r/   r   r!   r4   r6   rM   r   r   r   float8e4m3_to_float32c   s   
rT   c           	      C  sN  |r|r| dkrt t jS d}n5|sB|sB| dv r t t j S | dv r*t t jS | dkr5t t j S | dkr?t t jS d}ntdt | } | d@ d	? }| d
@ }| d@ }|d> }|dkr|dkrd| }|d	@ dkr{|dM }|dK }|d8 }||d@ d> O }||d> O }n||d> O }|d| 7 }||d> O }t |t j}|S )Nr:   r$   >         r8   >   }   ~   r<      |      z%fn and uz must be both False or True.r   r>   r?   r   r<   r      rB   rA   )r)   r.   rF   infrD   rG   r-   rH   r   r   r   _float8e5m2_to_float32_scalar   sF   
r^   c                 C  s$   t | ||d}|du r|S ||S )a  Converts ndarray of float8, e5m2 (as uint32) to f32 (as uint32).

    See :ref:`onnx-detail-float8` for technical details.

    Args:
        data: A numpy array, empty dimensions are allowed if dims is None.
        dims: If specified, the function reshapes the results.
        fn: No infinite values.
        uz: No negative zero.

    Returns:
        A numpy array of float32 with the same dimension if dims is None,
        or reshaped to dims if specified
    rQ   N)_float8e5m2_to_float32r/   rS   r   r   r   float8e5m2_to_float32   s   
r`   z_Deprecated since 1.18. Scheduled to remove in 1.20. Consider implementing your own unpack logicnp.int32 | np.ndarrayint | Sequence[int]signedc                   s    fdd}t |dd}||  \}}t j|j|j ft jd}||ddd< ||ddd< |jt |d krB| dd }||}|S )	a  Converts ndarray of int4 (as packed uint8) to f32
    See :ref:`onnx-detail-int4` for technical details.

    Args:
        data: A numpy array, empty dimensions are allowed if dims is
            None.
        dims: The dimensions are used to reshape the unpacked buffer
        signed: Whether the 4 bit integer is signed or unsigned

    Returns:
        A numpy array of float32 reshaped to dims.
    c                   s   t |  S N)r
   _unpack_single_4bitx2r%   rc   r   r   r'      s    zunpack_int4.<locals>.<lambda>r   r   dtyper   N)r)   
frompyfuncravelemptysizer.   prodr/   )r   r!   rc   single_funcfuncres_highres_lowrM   r   rf   r   unpack_int4   s   
rs   r&   npt.NDArray[np.uint8]npt.NDArray[np.float32]c                 C  sp   t t | ddd}| d@ t j}| d@ d? t j}t |dk||d  |d|d   d|d   }|S )aN  Evaluate the numerical value of an array of unpacked float4e2m1 values (as uint8)
    See :ref:`onnx-detail-int4` for technical details.

    Args:
        x: an array of uint8 elements representing a float4e2m1 (using the 4 LSB)

    Returns:
        An array of float32 elements representing the values of the float4e2m1 input.
    r9   ri   r      r   g       @g      ?)r)   wherebitwise_andr+   r.   )r&   rL   mantissaexponentvalr   r   r   unpacked_float4e2m1_to_float32   s   
r|   c                 C     t | |}t|S )a]  Converts ndarray of float4e2m1 (as packed uint8) to f32
    See :ref:`onnx-detail-float4` for technical details.

    Args:
        data: A numpy array, empty dimensions are allowed if dims is
            None.
        dims: The dimensions are used to reshape the unpacked buffer

    Returns:
        A numpy array of float32 reshaped to dims.
    )_unpack_uint4r|   )r   r!   rM   r   r   r   unpack_float4e2m1  s   
r   c                 C  s   t j| jd g| jd}| t d@ }| t d@ }|t dL }||ddd< ||ddd< |jt |d kr?|dd	 }|j|d
d |S )a  Convert a packed uint4 array to unpacked uint4 array represented as uint8.

    Args:
        data: A numpy array.
        dims: The dimensions are used to reshape the unpacked buffer.

    Returns:
        A numpy array of int8/uint8 reshaped to dims.
    r   rg   r[      r@   r   Nr   ri   F)refcheck)r)   rl   rm   rh   uint8rn   resize)r   r!   result	array_low
array_highr   r   r   r~     s   r~   npt.NDArray[np.int8]c                 C  s"   t | d? dk| | dB t jS )z4Extend 4-bit signed integer to 8-bit signed integer.r>   r   r   )r)   rw   r+   int8r%   r   r   r   _extend_int4_sign_bits8  s   "r   c                 C  r}   )aH  Convert a packed (signed) int4 array to unpacked int4 array represented as int8.

    The sign bit is extended to the most significant bit of the int8.

    Args:
        data: A numpy array.
        dims: The dimensions are used to reshape the unpacked buffer.

    Returns:
        A numpy array of int8 reshaped to dims.
    )r~   r   )r   r!   unpackedr   r   r   _unpack_int4=  s   
r    tensorr   base_dirstrc                 C  sv  |  dr	td| jtjkrtd| j}t|}tt|}t	|}| j
}| jtjkrHt| |}dd |D }t|||S t| rQt| | |  dr&| j}	tjdkrjtj|	|d  }	|tjkrtj|	tjd|}
|
tjS |tjkrtj|	tjd|}
|
tj S |tj!krtj|	tjd|}
|
tj"S |tj#krtj|	tjd|}
|
tj$S |tj%krtj|	tjd|}
|
tj&S |tj'krtj|	tj(d}
t)|
|tj*S |tj+krtj|	tj(d}
t,|
|tj-S |tj.krtj|	tj(d}
t)|
|tj/S tj|	|d|S |tj0kr<tj| j1tj2d|tj3S |tjkrXtj| j1tj4dtj2|}
|
tjS |tjkrttj| j1tj4dtj(|}
|
tj S |tj!krtj| j1tj4dtj(|}
|
tj"S |tj#krtj| j1tj4dtj(|}
|
tj$S |tj%krtj| j1tj4dtj(|}
|
tj&S |tj'krtj| j1tj4dtj(}
t)|
|tj*S |tj+kr tj| j1tj4dtj(}
t,|
|tj-S |tj.krtj| j1tj4dtj(}
t)|
|tj/S t| |}
|tj5tj6fv r.t7|
}
tj|
|d||S )	a+  Converts a tensor def object to a numpy array.
    Supports types defined in :mod:`onnx._custom_element_types`.

    Args:
        tensor: a TensorProto object.
        base_dir: if external tensor exists, base_dir can help to find the path to it

    Returns:
        arr: the converted array.
    segmentz*Currently not supporting loading segments.z4The element type in the input tensor is not defined.c                 S  s   g | ]}| d qS )utf-8)decode)r   sr   r   r   r   i  s    zto_array.<locals>.<listcomp>raw_databigrg   )8HasFieldrE   	data_typer   	UNDEFINED	TypeErrorr	   tensor_dtype_to_np_dtype$tensor_dtype_to_storage_tensor_dtypetensor_dtype_to_fieldr!   STRINGgetattrr)   asarrayr+   r/   r   r   r   sys	byteorder
frombufferbyteswaptobytesBFLOAT16int16r-   custom_np_typesbfloat16FLOAT8E4M3FNr   float8e4m3fnFLOAT8E4M3FNUZfloat8e4m3fnuz
FLOAT8E5M2
float8e5m2FLOAT8E5M2FNUZfloat8e5m2fnuzUINT4r   r~   uint4INT4r   int4
FLOAT4E2M1
float4e2m1FLOAT16
int32_datauint16float16r,   	COMPLEX64
COMPLEX128r   )r   r   tensor_dtypenp_dtypestorage_np_dtypestorage_fieldr!   utf8_stringsssr   r   r   r   r   to_arrayO  s   












r   arrname
str | Nonec              
   C  st  t | tjtjfstdt|  t }|j| j	 |r!||_
| jtks.t| jtjrt| j|_|  }|D ]K}t |trL|j|d q;t |tjrr|D ]}t |tre|j|d qTt |trp|j| qTq;t |tr~|j| q;tdtt||S zt| j}W n ty } z	td| j|d}~ww ||_|  |_tjdkrt| |S )zConverts a numpy array to a tensor def.

    Args:
        arr: a numpy array.
        name: (optional) the name of the tensor.

    Returns:
        TensorProto: the converted tensor def.
    z2arr must be of type np.generic or np.ndarray, got r   zMUnrecognized object in the object array, expect a string, or array of bytes: z$Numpy data type not understood yet: Nr   ) 
isinstancer)   ndarraygenericr   typer   r!   extendr(   r   rh   object
issubdtypestr_r	   np_dtype_to_tensor_dtyper   flattenr   string_dataappendencodebytesrD   KeyErrorRuntimeErrorr   r   r   r   _convert_endian)r   r   r   
flat_arrayer   rh   r   r   r   _from_array  sP   








r   c           	      C  s*  t | tjst| |S | j}|tjkr#|jd d dkr#tj	}tj
}n|tjkr8|jd d dkr8tj}tj
}n|tjkrM|jd d dkrMtj}tj
}nn|tjkrb|jd d dkrbtj}tj
}nY|tjkrw|jd d dkrwtj}tj}nD|tjkr|jd d dkrtj}tj}n/|tjkr|jd d dkrtj}tj
}n|tjkr|jd d d	krtj}tj
}nt| |S |tjtjtjfv r| | }|jd
 dkrtd| j d|ddd
 d@ |ddd
 d>  }t }|j !| j |r||_"|# |_$||_%|S t| ||}||_%|S )a  Converts an array into a TensorProto including
    supported type defined in :mod:`onnx._custom_element_types`.

    Args:
        tensor: a numpy array.
        name: (optional) the name of the tensor.

    Returns:
        TensorProto: the converted tensor def.
    r   e4m3fne4m3fnuze5m2e5m2fnuzr   r   r   r   r   r   zIThe conversion of a tensor of INT4 or UINT4 requires an even size (shape=z+). Every byte stores two INT4 or two UINT4.Nr[   r@   )&r   r)   r   r   rh   r   r   descrr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r+   rk   rm   rE   r(   r!   r   r   r   r   r   )	r   r   dttodt_tovaluebufferpbtr   r   r   
from_array  s^   

$
r   sequencer   	list[Any]c                 C  sv   | j }|tjkrdd | jD S |tjkrdd | jD S |tjkr*dd | jD S |tjkr7dd | j	D S t
d)zConverts a sequence def to a Python list.

    Args:
        sequence: a SequenceProto object.

    Returns:
        list: the converted list.
    c                 S     g | ]}t |qS r   r   r   vr   r   r   r   d      zto_list.<locals>.<listcomp>c                 S  r   r   r   r   r   r   r   r   f  r   c                 S  r   r   )to_listr   r   r   r   r   h  r   c                 S  r   r   )to_dictr   r   r   r   r   j  r   z8The element type in the input sequence is not supported.)	elem_typer   TENSORtensor_valuesSPARSE_TENSORsparse_tensor_valuesSEQUENCEsequence_valuesMAP
map_valuesr   )r   r   r   r   r   r   Y  s   	



r   lstrh   
int | Nonec           	        s  t  }|r||_|r|}n#t dkr- d }t|tr t j}nt|tr)t j}nt j}nt j}||_	t dkrHt
 fdd D sHtd|t jkr] D ]}|jt|g qO|S |t jkrr D ]}|jt|g qd|S |t jkr D ]}|jt|g qy|S td)a]  Converts a list into a sequence def.

    Args:
        lst: a Python list
        name: (optional) the name of the sequence.
        dtype: (optional) type of element in the input list, used for specifying
                          sequence values when converting an empty list.

    Returns:
        SequenceProto: the converted sequence def.
    r   c                 3  s"    | ]}t |t d  V  qdS )r   N)r   r   )r   elemr   r   r   	<genexpr>  s     zfrom_list.<locals>.<genexpr>zqThe element type in the input list is not the same for all elements and therefore is not supported as a sequence.zZThe element type in the input list is not a tensor, sequence, or map and is not supported.)r   r   r   r   dictr   listr   r   r   allr   r   r   r   r   	from_listr   	from_dict)	r   r   rh   r   r   
first_elemr   seqmappingr   r   r   r  n  sB   

"

	
r  	map_protor   dict[Any, Any]c                 C  s`   g }| j tjkrt| j}nt| j}t| j}t|t|kr't	d| j
dtt||}|S )zConverts a map def to a Python dictionary.

    Args:
        map_proto: a MapProto object.

    Returns:
        The converted dictionary.
    z2Length of keys and values for MapProto (map name: z) are not the same.)key_typer   r   r   string_keyskeysr   valuesr   
IndexErrorr   r   zip)r  key_list
value_list
dictionaryr   r   r   r     s   	

r   dict_c                   s   t  }|r||_t| }t|d  t }tjtj	tj
tjtjtjtjtjg}t fdd|D s9tdt|  }t|d tfdd|D sUtdt|}||_|tjkrh|j| n
||v rr|j| |j| |S )zConverts a Python dictionary into a map def.

    Args:
        dict_: Python dictionary
        name: (optional) the name of the map.

    Returns:
        MapProto: the converted map def.
    r   c                 3      | ]
}t | kV  qd S rd   r)   result_type)r   key)raw_key_typer   r   r         zfrom_dict.<locals>.<genexpr>zfThe key type in the input dictionary is not the same for all keys and therefore is not valid as a map.c                 3  r  rd   r  )r   r{   )raw_value_typer   r   r     r  zjThe value type in the input dictionary is not the same for all values and therefore is not valid as a map.)r   r   r   r)   r  r	   r   r   INT8INT16INT32INT64UINT8UINT16UINT32UINT64r  r   r  r  r	  r   r
  r   r  CopyFrom)r  r   r  r  r	  valid_key_int_typesr  	value_seqr   )r  r  r   r    sB   


r  optionalr   
Any | Nonec                 C  s   | j }|tjkr
dS |tjkrt| jS |tjkrt| jS |tjkr(t	| j
S |tjkr2t| jS |tjkr<t| jS td)zConverts an optional def to a Python optional.

    Args:
        optional: an OptionalProto object.

    Returns:
        opt: the converted optional.
    Nz8The element type in the input optional is not supported.)r   r   r   r   r   tensor_valuer   sparse_tensor_valuer   r   sequence_valuer   r   	map_valueOPTIONALto_optionaloptional_valuer   )r%  r   r   r   r   r,    s   	










r,  optc                 C  s   t  }|r||_|dur|t j vrt| d|}nt| tr&t j}nt| tr/t j	}n| du r7t j
}nt j}||_| durr|t jkrP|jt|  |S |t j	kr_|jt|  |S |t jkrn|jt|  |S td|S )a  Converts an optional value into a Optional def.

    Args:
        opt: a Python optional
        name: (optional) the name of the optional.
        dtype: (optional) type of element in the input, used for specifying
                          optional values when converting empty none. dtype must
                          be a valid OptionalProto.DataType value

    Returns:
        optional: the converted optional def.
    Nz( must be a valid OptionalProto.DataType.zUThe element type in the input is not a tensor, sequence, or map and is not supported.)r   r   DataTyper  r   r   r   r   r   r   r   r   r   r'  r"  r   r)  r  r*  r  )r.  r   rh   r%  r   r   r   r   from_optional  s:   





r0  Nonec                 C  s.   | j }t|}tj| j|d  | _dS )znCall to convert endianness of raw data in tensor.

    Args:
        tensor: TensorProto to be converted.
    rg   N)r   r	   r   r)   r   r   r   r   )r   r   r   r   r   r   r   B  s   
r   r   input_shape
tuple[int]np.dtypeseedc              	   C  s   t j| |t jt jt jt jt jt jt j	t j
fv rBtt |jt t j	j}tt |jt t j	j}t jj||| d|S t| d)a'  Create random integer array for backend/test/case/node.

    Args:
        input_shape: The shape for the returned integer array.
        dtype: The NumPy data type for the returned integer array.
        seed: The seed for np.random.

    Returns:
        np.ndarray: Random integer array.
    )rm   z' is not supported by create_random_int.)r)   randomr5  r   r   rG   uint64r   r   r,   int64miniinfomaxrandintr+   r   )r2  rh   r5  endstartr   r   r   create_random_intO  s   r?  )r   r   r   r   rd   )r   r    r!   r"   r   r#   )r2   r3   r4   r5   r6   r5   r   r7   )NTF)
r   r    r!   r"   r4   r5   r6   r5   r   r#   )NFF)r   ra   r!   rb   rc   r5   r   r#   )r&   rt   r   ru   )r   rt   r!   r   r   r#   )r   rt   r!   r   r   rt   )r&   rt   r   r   )r   rt   r!   r   r   r   )r   )r   r   r   r   r   r#   )r   r#   r   r   r   r   )r   r#   r   r   r   r   )r   r   r   r   )NN)r   r   r   r   rh   r   r   r   )r  r   r   r  )r  r  r   r   r   r   )r%  r   r   r&  )r.  r&  r   r   rh   r   r   r   )r   r   r   r1  )r   )r2  r3  rh   r4  r5  r3   r   r#   )6
__future__r   r   typingr   r   numpyr)   numpy.typingnpttyping_extensionsonnx._custom_element_types_custom_element_typesr   onnxr   r   r   r   r	   r
   onnx.external_data_helperr   r   collections.abcr   r   
deprecatedDeprecationWarningr1   rO   	vectorizerR   rT   r^   r_   r`   rs   r|   r   r~   r   r   r   r   r   r   r  r   r  r,  r0  r   r?  r   r   r   r   <module>   s    

*
(
!



 
A
@
9
5
3