o
    es7                  	   @   s  d dl Z d dlmZmZmZmZmZmZ d dlZ	d dl
mZmZmZmZmZ d dlmZmZ dee dee fddZd	e	jd
eeee f de	jfddZd+dedede	jfddZd,de	jdee defddZdedee fddZd-dee dee dee defddZdedeeef fddZd,d eeef dee defd!d"Zd#edee fd$d%Z		d-d&ee dee dee defd'd(Z deddfd)d*Z!dS ).    N)AnyDictListOptionalSequenceUnion)MapProtoOptionalProtoSequenceProtoTensorProtomapping)load_external_data_for_tensoruses_external_datafareturnc                    s    fddt t d D S )Nc                    s*   g | ]}t  |d    |d  d  qS )      )complex).0ir    AD:\Projects\ConvertPro\env\Lib\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   datadimsc                 C   s&   dd }||  tj|tjS )z8Converts ndarray of bf16 (as uint32) to f32 (as uint32).c                 S   s   | d> S )N   r   )xr   r   r   <lambda>   s    z%bfloat16_to_float32.<locals>.<lambda>)astypenpint32reshapeviewZfloat32)r   r   shiftr   r   r   bfloat16_to_float32   s   r(    tensorbase_dirc                 C   s  |  dr	td| jtjkrtd| j}tj| }tj| }tj| }tj	| }| j
}| jtjkrLt| |}tdd |D }	t|	||S t| rUt| | |  drtjdkrct|  |tjkrvtj| jtjd}
t|
|S tj| j|d|S |tjkrtj| jtjd|tj S |tjkrtj| jtj!d}
t|
|S t| |}
|tj"ks|tj#krt$|
}
tj|
|d||S )	zConverts a tensor def object to a numpy array.

    Inputs:
        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    | ]}| d V  qdS )utf-8N)decode)r   sr   r   r   	<genexpr>.       zto_array.<locals>.<genexpr>raw_databigdtype)%ZHasField
ValueError	data_typer   	UNDEFINED	TypeErrorr   TENSOR_TYPE_TO_NP_TYPEZ"TENSOR_TYPE_TO_STORAGE_TENSOR_TYPEZSTORAGE_TENSOR_TYPE_TO_FIELDr   STRINGgetattrlistr#   Zasarrayr"   r%   r   r   sys	byteorderconvert_endianZBFLOAT16
frombufferr2   Zint16r(   ZFLOAT16Z
int32_dataZuint16r&   Zfloat16r$   Z	COMPLEX64Z
COMPLEX128r   )r*   r+   tensor_dtypenp_dtypeZstorage_typeZstorage_np_dtypeZstorage_fieldr   Zutf8_stringsssr   r   r   r   to_array   sh   
	















rE   arrnamec                 C   s8  t  }|j| j |r||_| jtkrotj| j |_	| 
 }|D ]K}t|tr2|j|d q!t|tjrX|D ]}t|trK|j|d q:t|trV|j| q:q!t|trd|j| q!tdtt||S ztj| j }W n ty   tdt| j w ||_	|  |_tjdkrt| |S )zConverts a numpy array to a tensor def.

    Inputs:
        arr: a numpy array.
        name: (optional) the name of the tensor.
    Returns:
        TensorProto: the converted tensor def.
    r-   zMUnrecognized object in the object array, expect a string, or array of bytes: z$Numpy data type not understood yet: r3   )r   r   extendshaperG   r5   objectr   NP_TYPE_TO_TENSOR_TYPEr7   flatten
isinstancestrZstring_dataappendencoder#   ndarraybytesNotImplementedErrortypeKeyErrorRuntimeErrortobytesr2   r>   r?   r@   )rF   rG   r*   Z
flat_arrayer/   r5   r   r   r   
from_array`   sH   	







rY   sequencec                 C   s   g }| j }tj| }t| |}|D ]1}|tjks|tjkr%|t| q|tj	kr2|t
| q|tjkr?|t| qtd|S )zConverts a sequence def to a Python list.

    Inputs:
        sequence: a SequenceProto object.
    Returns:
        list: the converted list.
    z8The element type in the input sequence is not supported.)	elem_typer   ZSTORAGE_ELEMENT_TYPE_TO_FIELDr<   r
   TENSORSPARSE_TENSORrO   rE   SEQUENCEto_listMAPto_dictr9   )rZ   lstr[   value_fieldvaluesvaluer   r   r   r_      s   



r_   rb   r5   c           	         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.

    Inputs:
        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)rM   rT   )r   elemrb   r   r   r0      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
   rG   r   rM   dictr`   r=   r^   r\   r[   allr9   Ztensor_valuesrH   rY   Zsequence_values	from_listZ
map_values	from_dict)	rb   rG   r5   rZ   r[   Z
first_elemr*   seqmapr   rg   r   rj      s:   

"



rj   rm   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.

    Inputs:
        map: a MapProto object.
    Returns:
        dict: the converted dictionary.
    z2Length of keys and values for MapProto (map name: z) are not the same.)key_typer   r;   r=   string_keyskeysr_   rd   r   
IndexErrorrG   rh   zip)rm   Zkey_listZ
value_list
dictionaryr   r   r   ra      s   

ra   rh   c                    s   t  }|r||_t|  }t|d j tj  }t	j
t	jt	jt	jt	jt	jt	jt	jg}t fdd|D s<tdt|  }t|d tfdd|D sWtdt|}||_|t	jkrj|j| n
||v rt|j| |j| |S )zConverts a Python dictionary into a map def.

    Inputs:
        dict: Python dictionary
        name: (optional) the name of the map.
    Returns:
        MapProto: the converted map def.
    r   c                 3       | ]}t | V  qd S NrM   )r   key)raw_key_typer   r   r0     r1   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   rt   ru   rv   )r   val)raw_value_typer   r   r0     r1   zjThe value type in the input dictionary is not the same for all values and therefore is not valid as a map.)r   rG   r=   rp   r#   arrayr5   r   rK   r   ZINT8ZINT16ZINT32ZINT64ZUINT8ZUINT16ZUINT32ZUINT64ri   r9   rd   rT   rj   rn   r;   ro   rH   CopyFrom)rh   rG   rm   rp   rn   Zvalid_key_int_typesrd   Z	value_seqr   )rx   rz   r   rk      s0   	

rk   optionalc                 C   s   d}| j }|tjkr|S tj| }t| |}|tjks |tjkr&t|}|S |tj	kr1t
|}|S |tjkr<t|}|S |tjkrEt|S td)zConverts an optional def to a Python optional.

    Inputs:
        optional: an OptionalProto object.
    Returns:
        opt: the converted optional.
    Nz8The element type in the input optional is not supported.)r[   r	   r8   r   ZOPTIONAL_ELEMENT_TYPE_TO_FIELDr<   r\   r]   rE   r^   r_   r`   ra   ZOPTIONALto_optionalr9   )r}   optr[   rc   re   r   r   r   r~   $  s$   


	


r~   r   c                 C   s   t  }|r||_|rdd t j D }||v sJ |}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.

    Inputs:
        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.
    c                 S   s   g | ]}|qS r   r   )r   vr   r   r   r   W  s    z!from_optional.<locals>.<listcomp>NzUThe element type in the input is not a tensor, sequence, or map and is not supported.)r	   rG   ZDataTyperd   rM   rh   r`   r=   r^   r8   r\   r[   Ztensor_valuer|   rY   Zsequence_valuerj   Z	map_valuerk   r9   )r   rG   r5   r}   Zvalid_dtypesr[   r   r   r   from_optional@  s6   




r   c                 C   s.   | j }tj| }tj| j|d  | _dS )z
    Call to convert endianess of raw data in tensor.

    Arguments:
        tensor (TensorProto): TensorProto to be converted.
    r4   N)r7   r   r:   r#   rA   r2   byteswaprW   )r*   rB   rC   r   r   r   r@   r  s   
r@   )r)   ru   )NN)"r>   typingr   r   r   r   r   r   numpyr#   Zonnxr   r	   r
   r   r   Zonnx.external_data_helperr   r   intr   r   rQ   r(   rN   rE   rY   r_   rj   ra   rk   r~   r   r@   r   r   r   r   <module>   s4    &J:(2$)
2