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   Z/home/ubuntu/vllm_env/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   appendinitializersortoutput
ClearFieldextend)graph
deps_countdeps_to_nodessorted_nodesnode_idxr   
input_nameinitializer_namesgraph_input_namesinput_names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   UINT8UINT16UINT32UINT64INT8INT16INT32INT64FLOAT16r+   BOOL	UNDEFINED)qnn_data_typer   r   r	   qnn_data_type_to_onnx_data_typeH   s.   rC   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.tensorsz6QNN converted json file not valid. Can't find tensors.type	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   rC   r,   r-   r   )qnn_json_file_pathqnn_input_output_tensor_dicqnn_json_fileqnn_jsonqnn_tensor_nameqnn_tensor_attribute
qnn_tensorr   r   r	   parse_qnn_json_filen   s,   



rS   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	onnx_dimsqnn_dimsr   r	   r
      s     z4compare_onnx_shape_with_qnn_shape.<locals>.<genexpr>)r   allrangerV   r   rV   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   rZ   rankpermrU   r   r   r	   gen_to_channel_first_perm   s   
rb   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   

rc   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requiredrE   z-qz
--qnn_jsonz4Required. Path to Qnn converted model_net.json file.	_qnn_castCast)r   inputsoutputsto
_qnn_trans	Transpose)r   rh   ri   ra   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_argsrS   rO   onnxrJ   
onnx_modelr   r   r   rE   tensor_type	elem_typer,   r   	make_noder   r[   shaper-   rb   r   rZ   rT   AssertionErrorr   rc   r   r   r(   savereplace)parserargsrM   modelnodes_to_addgraph_input_output_name_dicgraph_inputinput_name_fater_node_insertqnn_input_tensorcast_input_namecast_output_nameinput_cast_nodetranspose_permtranspose_input_nametranspose_output_nameinput_transpose_noderU   graph_outputoutput_name_after_node_insertqnn_output_tensoroutput_cast_nodeoutput_transpose_noder   node_input_index
node_inputnode_output_indexnode_outputr   r   r	   main   s   










r   __main__)rI   argparser   rp   r   r   r(   r)   rC   rS   r[   rb   rc   r   r0   r   r   r   r	   <module>   s   4&~
