o
    soinS                     @  s   d dl mZ d dlZd dlmZmZ d dlZd dlZd dl	mZ
 d dlZd dlmZ er2d dlmZ 		dOdPddZdQddZdRddZdQddZdRddZdSdTd"d#ZdUd%d&ZdVdWd)d*ZdXd.d/Z	dYdZd3d4Zd[d8d9ZdVd\d;d<Zd]d@dAZ	dYd^dCdDZ	Ed_d`dKdLZdadMdNZdS )b    )annotationsN)TYPE_CHECKINGAny)helper)SequenceTupx
np.ndarraysaturatebool
round_modestrreturnc                 C  s  t j| t jd}|t j}|d? d@ }|t j}|dk}t j|t jd}d||< | }|dkr|d@ dkt j}	|d@ dkt j}
|d@ dkt j}|dkt j}|	d	k|
d	k|d	kB |d	kB @ }t |}d	|||@ < |r|d
k|@ |@ }d||< ||7 }n/|dkr|d@ dk}||@ }|r|d
k|@ }d||< ||t j7 }n|dkrnt	d| |t j}|| ||< |t
jS )ar  Convert float32 NumPy array to float8e8m0 representation. If the input
    is not a float32 array, it will be cast to one first.

    Args:
        x: Input array to convert.
        saturate: Whether to saturate at max/min float8e8m0 value.
        round_mode: "nearest", "up", or "down".

    Returns:
        np.ndarray: Array of ml_dtypes.float8_e8m0fnu values.
    dtype      nearesti  @ r   i    i       r   iO FdownzUnsupported rounding mode: )npasarrayfloat32viewuint32astypeuint16
zeros_likeuint8
ValueError	ml_dtypesfloat8_e8m0fnu)r   r
   r   x_f32f_bitsexponentspecial_maskoutputnormal_maskgrslsbround_up	incrementmax_maskhas_fraction r1   E/home/ubuntu/.local/lib/python3.10/site-packages/onnx/numpy_helper.pyto_float8e8m0   sF    

r3   datanpt.NDArray[np.uint8]dimsSequence[int]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            r   Nr   Frefcheck)r   emptysizer   r   prodresize)r4   r6   result	array_low
array_highr1   r1   r2   _unpack_4bit_   s   rF   arrayc                 C  sx   |   tj }| j}|d dk}|r|j|d gdd |dM }|ddd  dK  < |ddd |ddd B S )	z[Convert a numpy array to flatten, packed int4/uint4. Elements must be in the correct range.r8   r   Fr=   r9   Nr;   r   ravelr   r   r   copyr@   rB   )rG   
array_flatr@   	odd_sizedr1   r1   r2   _pack_4bitx2x   s   rM   c                 C  s   t j| jd g| jd}| d@ |ddd< | d? d@ |ddd< | d? d@ |ddd< | d? d@ |ddd< |jt |krG|dt | }|j|d	d
 |S )a  Convert a packed uint2 array to unpacked uint2 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;   r      r   Nr8   r      Fr=   )r   r?   r@   r   rA   rB   )r4   r6   rC   r1   r1   r2   _unpack_2bit   s   rP   c                 C  s   |   tj }| j}|d }|r|j|d|  gdd |dM }|ddd  dK  < |ddd  dK  < |ddd  dK  < |d	dd |ddd B |ddd B |ddd B S )
z[Convert a numpy array to flatten, packed int2/uint2. Elements must be in the correct range.r;   Fr=   rN   r   Nr8   rO   r   rH   )rG   rK   r@   pad_lenr1   r1   r2   _pack_2bitx4   s   8rR    tensoronnx.TensorProtobase_dirc                 C  s  |  dr	td| jtjjkrtd| j}t|}tt	|}t
|}| j}| jtjjkrJt| |}dd |D }t|||S tj| rWtj| | |  dr| j}	tjdkrotj|	|d  }	|tjjtjjtjjhv rtj|	tjd}
t|
| |S |tjj!tjj"hv rtj|	tjd}
t#|
| |S tj|	|d|S |tjj$tjj%tjj&tjj'hv rtj(| j)tj*d tj+tj,| |S |tjj-tjj.tjj/tjj0tjj1tjj2hv rtj(| j)tj*d tj+tj ||S |tjjtjjtjjhv r,tj(| j)tj*d tj+tj}
t|
| |S |tjj!tjj"hv rPtj(| j)tj*d tj+tj}
t#|
| |S t| |}
|tjj3tjj4fv rntj(|
|dj |d|S tj|
|d||S )	a6  Converts a tensor def object to a numpy array.

    This function uses ml_dtypes if the dtype is not a native numpy dtype.

    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.z2The element type in the input tensor is UNDEFINED.c                 S  s   g | ]}| d qS )utf-8)decode).0r+   r1   r1   r2   
<listcomp>   s    zto_array.<locals>.<listcomp>raw_databigr   )5HasFieldr    	data_typeonnxTensorProto	UNDEFINED	TypeErrorr   tensor_dtype_to_np_dtype$tensor_dtype_to_storage_tensor_dtypetensor_dtype_to_fieldr6   STRINGgetattrr   r   r   reshapeexternal_data_helperuses_external_dataload_external_data_for_tensorr\   sys	byteorder
frombufferbyteswaptobytesINT4UINT4
FLOAT4E2M1r   rF   r   UINT2INT2rP   BFLOAT16FLOAT16INT16UINT16rG   
int32_dataint32r   r   FLOAT8E4M3FNFLOAT8E4M3FNUZ
FLOAT8E5M2FLOAT8E5M2FNUZ
FLOAT8E8M0BOOL	COMPLEX64
COMPLEX128)rT   rV   tensor_dtypenp_dtypestorage_np_dtypestorage_fieldr6   utf8_stringsssr\   r4   r1   r1   r2   to_array   s   





	  
r   bytesc                 C  s<   | j jdkstjdkr| j jdkr| | j d} |  S )zConverts an array into bytes in little endian byte order.

    Args:
        array: a numpy array.

    Returns:
        bytes: Byte representation of passed array in little endian byte order.

    .. versionadded:: 1.20
    >r]   =<)r   rn   rm   r   newbyteorderrq   )rG   r1   r1   r2   tobytes_little_endian  s   r   name
str | Nonec                C  s   t  }|j| j |r||_| jtkst	| jtj
rPt jj|_|  }|D ]%}t|tr9|j|d q(t|trE|j| q(tdtt||S t| j}|t jjt jjt jjhv rgt| } |t jjt jjhv rut| } t| |_ ||_|S )zConverts an array into a TensorProto including

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

    Returns:
        TensorProto: the converted tensor def.
    rX   zMUnrecognized object in the object array, expect a string, or array of bytes: )!r`   ra   r6   extendshaper   r   objectr   
issubdtypestr_rg   r_   flatten
isinstancer   string_dataappendencoder   NotImplementedErrortyper   np_dtype_to_tensor_dtyperr   rs   rt   rM   ru   rv   rR   r   r\   )rG   r   rT   
flat_arrayer   r1   r1   r2   
from_array2  s@   

	



r   sequenceonnx.SequenceProto	list[Any]c                 C  s~   | j }|tjjkrdd | jD S |tjjkrdd | jD S |tjjkr-dd | jD S |tjj	kr;d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 r1   r   rZ   vr1   r1   r2   r[   x      zto_list.<locals>.<listcomp>c                 S  r   r1   r   r   r1   r1   r2   r[   z  r   c                 S  r   r1   )to_listr   r1   r1   r2   r[   |  r   c                 S  r   r1   )to_dictr   r1   r1   r2   r[   ~  r   z8The element type in the input sequence is not supported.)	elem_typer`   SequenceProtoTENSORtensor_valuesSPARSE_TENSORsparse_tensor_valuesSEQUENCEsequence_valuesMAP
map_valuesrc   )r   r   r1   r1   r2   r   m  s   	r   lstr   
int | Nonec           	        s,  t  }|r	||_|r|}n't dkr1 d }t|tr"t jj}nt|tr,t jj}n	t jj	}nt jj	}||_
t dkrMt fdd D sMtd|t jj	krf D ]}|jtt|g qU|S |t jjkr| D ]}|jt|g qn|S |t jjkr D ]}|jt|g q|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   )rZ   elemr   r1   r2   	<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   lenr   dictr   listr   r   r   allrc   r   r   r   r   r   r   	from_listr   	from_dict)	r   r   r   r   r   
first_elemrT   seqmappingr1   r   r2   r     sB   




"	r   	map_protoonnx.MapProtodict[Any, Any]c                 C  sb   g }| j tjjkrt| j}nt| j}t| j}t	|t	|kr(t
d| jdtt||dd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.F)strict)key_typer`   ra   rg   r   string_keyskeysr   valuesr   
IndexErrorr   r   zip)r   key_list
value_listr1   r1   r2   r     s   	

r   dict_c                   s  t  }|r	||_t| }t|d  t }t jj	t jj
t jjt jjt jjt jjt jjt jjh}t fdd|D sBtdt|  }t|d tfdd|D s^tdt|}||_|t jjkrr|j| n
||v r||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 Nr   result_type)rZ   key)raw_key_typer1   r2   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   r   r   )rZ   val)raw_value_typer1   r2   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`   MapProtor   r   r   r   r   r   ra   INT8ry   INT32INT64UINT8rz   UINT32UINT64r   rc   r   r   r   rg   r   r   r   CopyFrom)r   r   r   r   r   valid_key_int_typesr   	value_seqr1   )r   r   r2   r     sB   

r   optionalonnx.OptionalProto
Any | Nonec                 C  s   | j }|tjjkrdS |tjjkrt| jS |tjjkr!t| jS |tjj	kr,t
| jS |tjjkr7t| jS |tjjkrBt| 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`   OptionalProtorb   r   r   tensor_valuer   sparse_tensor_valuer   r   sequence_valuer   r   	map_valueOPTIONALto_optionaloptional_valuerc   )r   r   r1   r1   r2   r   	  s   	




r   optc                 C  s   t  }|r	||_|dur|t jj vrt| d|}n!t| tr)t jj}nt| t	r3t jj
}n| du r<t jj}nt jj}||_| dur{|t jjkrW|jt|  |S |t jj
krg|jt|  |S |t jjkrw|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   r   DataTyper   rc   r   r   r   r   r   rb   r   r   r   r   r   r   r   r   r   )r   r   r   r   r   r1   r1   r2   from_optional"  s:   





r   r   input_shape
tuple[int]np.dtypeseedintc              	   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.
    )r@   z' is not supported by create_random_int.)r   randomr   r   r   r   uint64int8int16r|   int64miniinfomaxrandintr   rc   )r   r   r   endstartr1   r1   r2   create_random_intU  s   r  c                 C  s^   t |t js|tjtjtjtjfv rt|}t 	| } nt
|}t | |j|j|S )zSaturate cast for numeric types.

    This function ensures that values outside the representable range
    of the target dtype are clamped to the maximum or minimum representable
    value of that dtype.
    )r   r   integerr!   int4uint4int2uint2r   roundfinfoclipr   r   r   )r   r   infor1   r1   r2   saturate_castt  s   

r  )Tr   )r   r	   r
   r   r   r   r   r	   )r4   r5   r6   r7   r   r5   )rG   r	   r   r5   )rS   )rT   rU   rV   r   r   r	   )rG   r	   r   r   r   )r   r   rG   r	   r   rU   )r   r   r   r   )NN)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   r   r   r   )r   )r   r   r   r   r   r   r   r	   )r   r	   r   r   r   r	   ) 
__future__r   rm   typingr   r   r!   numpyr   numpy.typingnptonnx.external_data_helperr`   r   collections.abcr   r3   rF   rM   rP   rR   r   r   r   r   r   r   r   r   r   r  r  r1   r1   r1   r2   <module>   s>   
K



r
;
9
54