o
    i4                     @   s   d dl Z d dlmZ d dlZd dlmZmZ dd ZG dd dZdd	 Zd
d Z	dd Z
dd Zdd Zdd ZedkrBe  dS dS )    N)ArgumentParser)TensorProtohelperc                 C   s  dgt | j }i }g }t| jD ]6\}}tdd |jD ||< || dkr0|| j|  q|jD ]}||vr?|g||< q3|| | q3qdd | jD }dd | jD }|| }	|	  d }
|	D ]*}|
|krkqd|}
||v r|| D ]}|| d ||< || dkr|| j|  quqdd}t |}||k r|| jD ]'}||v r|| D ]}|| d ||< || dkr|| j|  |d }qq|d }||k s|t | jksJ d| 	d	 | j
| d S )
Nr   c                 s   s    | ]}|rd V  qdS )   N ).0_r   r   ^/home/kim/smarthome/.venv/lib/python3.10/site-packages/onnxruntime/tools/qnn/add_trans_cast.py	<genexpr>   s    z)graph_topological_sort.<locals>.<genexpr>c                 S      g | ]}|j qS r   name)r   initr   r   r	   
<listcomp>       z*graph_topological_sort.<locals>.<listcomp>c                 S   r   r   r   )r   inputr   r   r	   r       r   r   zGraph is not a DAGnode)lenr   	enumeratesumr   appendZinitializersortoutputZ
ClearFieldextend)graphZ
deps_countZdeps_to_nodesZsorted_nodesZnode_idxr   Z
input_nameZinitializer_namesZgraph_input_namesZinput_namesZprev_input_namestartendr   r   r   r	   graph_topological_sort   sX   


r   c                   @   s   e Zd Zdd ZdS )QnnTensorStructc                 C   s   d| _ tj| _g | _d S )N )r   r   FLOATonnx_data_typedim)selfr   r   r	   __init__B   s   
zQnnTensorStruct.__init__N)__name__
__module____qualname__r$   r   r   r   r	   r   A   s    r   c                 C   s   | dks| dkrt jS | dks| dkrt jS | dks| dkr!t jS | dkr(t jS | dks0| d	kr3t jS | d
ks;| dkr>t jS | dksF| dkrIt jS | dkrPt jS | dkrWt j	S | dkr^t j
S | dkret jS t jS )Ni  i  i  i  i2  i2  id  i     i     i2  2   d   i  i2  i  )r   ZUINT8ZUINT16ZUINT32ZUINT64ZINT8ZINT16ZINT32ZINT64ZFLOAT16r    ZBOOLZ	UNDEFINED)Zqnn_data_typer   r   r	   qnn_data_type_to_onnx_data_typeH   s.   r,   c                 C   s   t | ^}t|}d|v sJ dd|d v sJ d|d d  D ]6\}}d|v r4d|v r4d|v s8J d|d d	ksD|d d
krZt }||_t|d |_|d |_|||< q$W d    n1 sew   Y  t	|d
kstJ dd S )Nr   z4QNN converted json file not valid. Can't find graph.Ztensorsz6QNN converted json file not valid. Can't find tensors.typeZ	data_typedimszDQNN converted json file not valid. Can't find some keys from tensorsr   r   zJConverted QNN model not valid. It should have at least 1 input & 1 output.)
openjsonloaditemsr   r   r,   r!   r"   r   )Zqnn_json_file_pathqnn_input_output_tensor_dicZqnn_json_fileqnn_jsonZqnn_tensor_nameZqnn_tensor_attributeZ
qnn_tensorr   r   r	   parse_qnn_json_filen   s,   



r5   c                    s8   t  t ksJ dt fddtt  D S )Nz,Onnx shape and Qnn shape has different rank.c                 3   s"    | ]} | j | kV  qd S )N)	dim_value)r   iZ	onnx_dimsZqnn_dimsr   r	   r
      s     z4compare_onnx_shape_with_qnn_shape.<locals>.<genexpr>)r   allranger8   r   r8   r	   !compare_onnx_shape_with_qnn_shape   s    r;   c                 C   sN   | dksJ dg }| d | | d  td| d D ]}| | q|S N   z,Shape rank should >2 for the Transpose node.r   r   r   r:   Zrankpermr7   r   r   r	   gen_to_channel_first_perm   s   
rA   c                 C   sF   | dksJ dg }| d td| D ]}| | q| d |S r<   r>   r?   r   r   r	   gen_to_channel_last_perm   s   

rB   c                  C   s`  t d} | jddddtd | jddd	dtd |  }i }t|j| t|j}g }i }|j	j
D ]}|j|v r|j}||j }|jjj|jkrq|}	|	d
 }
tjd|
|	g|
g|jjjd}|j|jj_||g |
}|
||j< t|jjjj|jstt|jjjj}|}|d }tjd||g|g|d}||g |||j< tt|jjjjD ]}|j| |jjjj| _qq2td|j d |j	jD ]}|j|v rX|j}||j }|jjj|jkr|}
|
d
 }	tjd|	|	g|
g|jd}|j|jj_||g |	}|	||j< t|jjjj|jsWtt|jjjj}|}|d }tjd||g|g|d}||g |||j< tt|jjjjD ]}||j j| |jjjj| _qDqtd|j d |j	jD ]1}t|j
D ]\}}||v r||| |j
|< qlt|jD ]\}}||v r|| |j|< qqe|j	j| t|j	 t ||j!dd d S )NzbInsert Cast, Transpose nodes into Onnx model to make it aligned with QNN generated context binary.z-mz--onnx_modelz"Required. Path to Onnx model file.T)helprequiredr-   z-qz
--qnn_jsonz4Required. Path to Qnn converted model_net.json file.Z	_qnn_castZCast)r   inputsoutputstoZ
_qnn_transZ	Transpose)r   rE   rF   r@   zError: Onnx model input: z  not exist from QNN model input.zError: Onnx model output: z! not exist from QNN model output.z.onnxz_add_trans.onnx)"r   add_argumentstr
parse_argsr5   r4   onnxr1   Z
onnx_modelr   r   r   r-   Ztensor_typeZ	elem_typer!   r   Z	make_noder   r;   shaper"   rA   r   r:   r6   AssertionErrorr   rB   r   r   r   savereplace)parserargsr3   modelZnodes_to_addZgraph_input_output_name_dicZgraph_inputZinput_name_fater_node_insertZqnn_input_tensorZcast_input_nameZcast_output_nameZinput_cast_nodeZtranspose_permZtranspose_input_nameZtranspose_output_nameZinput_transpose_noder7   Zgraph_outputZoutput_name_after_node_insertZqnn_output_tensorZoutput_cast_nodeZoutput_transpose_noder   Znode_input_indexZ
node_inputZnode_output_indexZnode_outputr   r   r	   main   s   










rS   __main__)r0   argparser   rK   r   r   r   r   r,   r5   r;   rA   rB   rS   r%   r   r   r   r	   <module>   s   4&~
