a
    hC                    @   s<  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
Z
edZG dd dZG dd dZG dd	 d	ZG d
d dZG dd dejZd+ddZdd Zdd ZG dd deZG dd dejZG dd deZdd Zdd Zdd  Zd!d" Zd#d$ ZG d%d& d&Zddd'd(d)d*ZdS ),    N)
NamedTupleOptionalZnnapi_serializec                   @   s@   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdS )NNAPI_OperandCoder                           	   
         N)__name__
__module____qualname__FLOAT32INT32ZUINT32TENSOR_FLOAT32TENSOR_INT32TENSOR_QUANT8_ASYMMBOOLTENSOR_QUANT16_SYMMZTENSOR_FLOAT16ZTENSOR_BOOL8ZFLOAT16ZTENSOR_QUANT8_SYMM_PER_CHANNELTENSOR_QUANT16_ASYMM r   r   N/var/www/auris/lib/python3.9/site-packages/torch/backends/_nnapi/serializer.pyr      s   r   c                   @   s  e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,d+Z-d,Z.d-Z/d.Z0d/Z1d0Z2d1Z3d2Z4d3Z5d4Z6d5Z7d6Z8d7Z9d8Z:d9Z;d:Z<d;Z=d<Z>d=Z?d>Z@d?ZAd@ZBdAZCdBZDdCZEdDZFdEZGdFZHdGZIdHZJdIZKdJZLdKZMdLZNdMZOdNZPdOZQdPZRdQZSdRZTdSZUdTZVdUZWdVZXdWZYdXZZdYZ[dZZ\d[Z]d\Z^d]Z_d^Z`d_Zad`S )aNNAPI_OperationCoder   r   r   r   r   r	   r
   r   r   r   r   r   r                                                                !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?   @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O   P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   N)br   r   r   ADDAVERAGE_POOL_2DCONCATENATIONCONV_2DDEPTHWISE_CONV_2DZDEPTH_TO_SPACE
DEQUANTIZEZEMBEDDING_LOOKUPZFLOORFULLY_CONNECTEDZHASHTABLE_LOOKUPZL2_NORMALIZATIONZ
L2_POOL_2DZLOCAL_RESPONSE_NORMALIZATIONLOGISTICZLSH_PROJECTIONZLSTMMAX_POOL_2DMULRELURELU1RELU6RESHAPEZRESIZE_BILINEARZRNNSOFTMAXZSPACE_TO_DEPTHZSVDFZTANHZBATCH_TO_SPACE_NDDIVMEANZPADZSPACE_TO_BATCH_NDZSQUEEZESTRIDED_SLICESUB	TRANSPOSEZABSZARGMAXZARGMINZAXIS_ALIGNED_BBOX_TRANSFORMZBIDIRECTIONAL_SEQUENCE_LSTMZBIDIRECTIONAL_SEQUENCE_RNNZBOX_WITH_NMS_LIMITZCASTZCHANNEL_SHUFFLEZDETECTION_POSTPROCESSINGEQUALZEXPEXPAND_DIMSZGATHERZGENERATE_PROPOSALSGREATERZGREATER_EQUALZGROUPED_CONV_2DZHEATMAP_MAX_KEYPOINTZINSTANCE_NORMALIZATIONLESSZ
LESS_EQUALLOGZLOGICAL_ANDZLOGICAL_NOTZ
LOGICAL_ORLOG_SOFTMAXZMAXIMUMZMINIMUMZNEGZ	NOT_EQUALZPAD_V2ZPOWPRELUQUANTIZEZQUANTIZED_16BIT_LSTMZRANDOM_MULTINOMIALZ
REDUCE_ALLZ
REDUCE_ANYZ
REDUCE_MAXZ
REDUCE_MINZREDUCE_PRODZ
REDUCE_SUMZ	ROI_ALIGNZROI_POOLINGZRSQRTZSELECTZSINZSLICEZSPLITZSQRTZTILEZTOPK_V2TRANSPOSE_CONV_2DZUNIDIRECTIONAL_SEQUENCE_LSTMZUNIDIRECTIONAL_SEQUENCE_RNNRESIZE_NEAREST_NEIGHBORr   r   r   r   r   %   s   r   c                   @   s   e Zd ZdZdZdZdZdS )NNAPI_FuseCoder   r   r   r   N)r   r   r   
FUSED_NONE
FUSED_RELUZFUSED_RELU1ZFUSED_RELU6r   r   r   r   r      s   r   c                   @   s   e Zd ZdZdZdZdS )OperandValueSourceTyper   r   r   N)r   r   r   	IMMEDIATENUMBERED_BUFFERZNUMBERED_MEMORYr   r   r   r   r      s   r   c                   @   s   e Zd ZdZdS )TorchScalarTypesr   N)r   r   r   QUINT8r   r   r   r   r      s   r   ư>c                 C   s   t | | |t| | kS N)absmin)lhsrhsZ	tolerancer   r   r   approx_equal   s    r   c              
   C   s@   t jdt jdt jdt jdt jdi}||  }|D ]}||9 }q.|S )Nr   r   r   )r   r   r   r   r   r   )op_typedimsZ
ITEM_SIZESsizedr   r   r   tensor_size   s    
r   c                 C   s   t | }|||< t|S r   )listtuple)tupindexvalueZlsr   r   r   change_element   s    r   c                   @   sj   e Zd ZU dZeed< eed< eed< eed< eed< eed< eed< eed	< eed
< eed< eed< dS )ConvPoolArgs2dz*Configuration arguments for a convolution.kernel_hkernel_wstride_hstride_wpad_tpad_bpad_lpad_r
dilation_h
dilation_wgroupN)r   r   r   __doc__int__annotations__r   r   r   r   r      s   
r   c                   @   s   e Zd ZdZdZdZdZdS )DimOrderr   r   r   i  N)r   r   r   PRESUMED_CONTIGUOUSCHANNELS_LASTSCALAR_OR_VECTORUNKNOWN_CONSTANTr   r   r   r   r      s   r   c                   @   sJ   e Zd ZU dZeed< eedf ed< eed< eed< eed< dd	 Z	d
S )Operandz"Represenation of an NNAPI operand.r   .shape	dim_orderscale
zero_pointc                 C   s,   | j tju rdS | j tju r dS tdd S )NTFzUnknown dim order)r   r   r   r   	Exceptionselfr   r   r   use_nchw   s
    zOperand.use_nchwN)
r   r   r   r   r   r   r   r   floatr   r   r   r   r   r      s   
r   c                 C   s   t | dksJ t |dks J t| }t|}t |t |krHtdt |t |kr`tdg }t||D ]X\}}|dkr|| qn|dkr|| qn||kr|| qntd|  d| qnt|S )Nr   z.Non-equal-rank broadcast is not supported yet.r   zCannot broadcast shapes: z and )lenr   r   zipappendr   )Zshape1Zshape2s1s2retd1Zd2r   r   r   broadcast_shapes   s0    r   c                 C   s   | \}}}}|j dks |jdkr(td|rn|d |j |j |j |j }|d |j |j |j	 |j	 }	n@||j |j |j |j d }||j |j	 |j
 |j d }	|dkrd}|dkrd}	||||	f}
|
S )Nr   zDilation not supported yet.r   )r   r   r   r   r   r   r   r   r   r   r   )Zimage_shapeargsZout_ch	transposebatchZ_in_cin_hin_wout_hout_w	out_shaper   r   r   get_conv_pool_shape  s     "  r   c                 C   s   |t ju r| S |t ju r@t| d gt| dd   | d g S |t ju rjt| dksft| dksfJ | S |t ju rx| S td|dd S )Nr   r   r   zBad dim_order: .)	r   r   r   r   r   r   r   r   r   r   r   r   r   r   	fix_shape$  s    

(

r   c                 C   s.   | t jt jfv r|S | t ju s"J g d| S )Nr   r   r   r   )r   r   r   r   )r   r   r   r   r   reverse_map_dim5  s    r   c                 C   s   d|  d| S )NZs__r   )op_iddimr   r   r   	flex_name@  s    r   c                )   @   sf  e Zd ZdddZdd Zdd Zdd	 Zd
d Zdd Ze	j
fddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Ze	jfd d!Zd"d# Zd$d% Zd&d' Zd(d) Zdd+d,Zdd-d.Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z d9d: Z!dd;d<Z"d=d> Z#dd?d@Z$dAdB Z%e&dCdD Z'dEdF dGdF dHdF dIdF dJdF dKdF dLdF dMdF dNdF dOdF dPdF dQdF dRdF dSdF dTdF dUdF dVdF dWdF dXdF dYdF dZdF d[dF d\dF d]dF d^dF d_dF d`dF dadF dbdF dcdF dddF dedF dfdF dgdF dhdF didF djdF dkdF dldF dmdF dn(Z(dodp Z)dqdr Z*dsdt Z+dudv Z,dwdx Z-dydz Z.d{d| Z/d}d~ Z0dd Z1dd Z2dd Z3dd Z4dd Z5dd Z6dd Z7dd Z8dd Z9d*dddZ:dd Z;dd Z<dd Z=dd Z>dd Z?dd Z@dd ZAdd ZBdd ZCdd ZDdd ZEdd ZFdd ZGdd ZHdddZIdd ZJdd ZKdd ZLdddZMdd ZNdd ZOd*S )_NnapiSerializerFc                 C   sp   g | _ g | _g | _g | _g | _g | _g | _g | _i | _i | _	i | _
i | _i | _g | _d| _|| _|d u rli }d S Nr   )operandsvalues
operations
value_dataoperation_argsinputsoutputs flexible_shape_computation_linesmodules	constantstensor_sequencesjitval_operand_mapcached_immediatesused_weightsZweight_offsetuse_int16_for_qint16)r   configr   r   r   r   __init__G  s$    z_NnapiSerializer.__init__c                 C   s
   t | jS r   )r   r   r   r   r   r   get_next_operand_id]  s    z$_NnapiSerializer.get_next_operand_idc                 C   sH   t |tsJ || jv r&td||  }| j| || j|< |S )NzDuplicate tensor: )
isinstancer   r   r   r   r   r   )r   jitvaloper
operand_idr   r   r   add_tensor_operandc  s    

z#_NnapiSerializer.add_tensor_operandc                 C   s&   t |tsJ |  }| j| |S r   )r   r   r   r   r   )r   r   r   r   r   r   add_anonymous_tensor_operandp  s    z-_NnapiSerializer.add_anonymous_tensor_operandc           	      C   s  t |jdd}d}d}|dkr*tj}n|dkr:tj}n|dkrZtj}| }| }n|dkrtj}| }| }|dksJ nn|d	kr| j	rt
|d
d }tjtjf}||v r|}|j}|j}qtd| dqtdntd|j dtt|j||||dS )Nztorch.         r   float32int32quint8qint32int16nnapi_dtypez `nnapi_type` needs to be one of z for `int16`y`int16` isn't supported. If you're trying to represent NNAPI qint16 with Pytorch int16, set `use_int16_for_qint16 = True`zCan't handle input with dtype '')r   r   r   r   r   )strdtypereplacer   r   r   r   q_scaleq_zero_pointr   getattrr   r   Znnapi_scaleZnnapi_zero_pointr   r   r   r   )	r   tensorr   r  r   r   r   r  Zop_codesr   r   r   torch_tensor_to_operandv  sT    

z(_NnapiSerializer.torch_tensor_to_operandc           	   
   C   sx   t |ddrtjntj}| ||}| ||}| j| t|j	D ],\}}|dkrF| 
||d| d| d qF|S )NZ
nnapi_nhwcFr   zargs[z].shape[])r
  r   r   r   r  r   r   r   	enumerater   compute_operand_shape)	r   arg_idxr   r  r   toperr   r   r   r   r   r   add_tensor_operand_for_input  s    
z-_NnapiSerializer.add_tensor_operand_for_inputc                 C   s   |  ||}t| j}| j| t|j|j}| j|tj	f t| j
}d}| jtd||| |tjkr|dddd}| j
| |S )Nr   iiir   r   r   )r  r   r   r   r   r   r   r   r   r   r   r   structpackr   r   permute)r   r  r   r  r   ZtsizeZbuf_numoffsetr   r   r   add_tensor_operand_for_weight  s    


z._NnapiSerializer.add_tensor_operand_for_weightc                 C   sv   t |tsJ ||f}|| jvrlt| j}| jt||tjdd | j	|t
jf | j| || j|< | j| S )Nr   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   )r   coder   r   	cache_keyr   r   r   r   add_immediate_operand  s    


z&_NnapiSerializer.add_immediate_operandc                 C   s   |  tjtd|dS )Nir   )r  r   r   r  r  r   r   r   r   r   add_immediate_int_scalar  s    z)_NnapiSerializer.add_immediate_int_scalarc                 C   s   |  tjtd|dS )Nfr   )r  r   r   r  r  r  r   r   r   add_immediate_float_scalar  s    z+_NnapiSerializer.add_immediate_float_scalarc                 C   s   |  tj|rdnddS )N       r   )r  r   r   r  r   r   r   add_immediate_bool_scalar  s    z*_NnapiSerializer.add_immediate_bool_scalarc                 C   s"   |  tjtd| t|fS Nr  )r  r   r   arraytobytesr   r  r   r   r   add_immediate_int_vector  s
    z)_NnapiSerializer.add_immediate_int_vectorc                 C   s
   || j v S r   )r   )r   r   r   r   r   has_operand_for_jitval  s    z'_NnapiSerializer.has_operand_for_jitvalc                 C   s   | j | }|| j| fS r   )r   r   )r   r   r   r   r   r   get_tensor_operand_by_jitval  s    
z-_NnapiSerializer.get_tensor_operand_by_jitvalc                 C   sF   |  |\}}|jD ](}|dkr(td|dk rtd| q||fS )Nr   z0Flexible size is not supported for this operand.z!Operand %s has runtime flex shape)r)  r   r   r   warning)r   r   r   r   sr   r   r   'get_tensor_operand_by_jitval_fixed_size  s    
z8_NnapiSerializer.get_tensor_operand_by_jitval_fixed_sizec                 C   s>   | j |}|d u r0| |d\}}| ||}|| j| fS N
TensorType)r   getget_constant_valuer  r   )r   r   r   r   r   r   r   r   r   get_tensor_operand_or_constant  s
    z/_NnapiSerializer.get_tensor_operand_or_constantc                 C   s(   |  |d\}}| |}|| j| fS r-  )r0  r  r   )r   r   r   r   r   r   r   r   get_tensor_operand_for_weight  s    
z._NnapiSerializer.get_tensor_operand_for_weightc                 C   s.   | j |t|t|f | j||  d S r   )r   r   r   r   extend)r   opcoder   r   r   r   r   add_operation  s    z_NnapiSerializer.add_operationc                 C   s   || j vsJ || j |< d S r   )r   )r   r   r   r   r   r   add_tensor_sequence  s    z$_NnapiSerializer.add_tensor_sequencec                 C   s    || j vsJ ||f| j |< d S r   )r   r   r   ctyper   r   r   r   add_constant_value  s    z#_NnapiSerializer.add_constant_valueNc                 C   sd   | j |}|d u r$td|d|\}}|d ur`| |kr`td| d|  d|d|S )Nz#Could not find constant value for 'z'.z Expected constant value of type z
, but got z for value 'r  )r   r/  r   kind)r   r   Ztypekindrecordr8  r   r   r   r   r0    s    
z#_NnapiSerializer.get_constant_valuec                 C   sH  |du r|j }nt|t|j ks&J dg}t|D ]`\}}|dkrT|t| n6|dkrn|t|| n|dkr|d ntd|d q4|d d	|}|jt	j
krd
| dS |jt	jkrd
| dS |jt	jkrd|j d|j d| dS |jt	jt	jfv r4| jr,d
| dS tdtd|j dS )zHReturn a TorchScript expression to build a template for a given operand.N(r   0z-Unknown dim value, dimensions should be >= -1,)r   ztorch.zeros(z, dtype=torch.float32)z, dtype=torch.int32)z0torch.quantize_per_tensor(torch.zeros(1), scale=z, zero_point=z, dtype=torch.quint8).expand(z).contiguous()z, dtype=torch.int16)r  z!Unsupported output operand type: )r   r   r  r   r  r   r   joinr   r   r   r   r   r   r   r   r   r   )r   r   r   r   Zshape_partsr   r+  Z
shape_coder   r   r   operand_to_template_torchscript%  sT    


z0_NnapiSerializer.operand_to_template_torchscriptc                 C   s   |  ||t|| d S r   )r  r   )r   Z	out_op_idZout_dimZin_op_idZin_dimr   r   r   forward_operand_shapeX  s    z&_NnapiSerializer.forward_operand_shapec                 C   s    | j t|| d|  d S )Nz = )r   r   r   )r   r   r   exprr   r   r   r  [  s    z&_NnapiSerializer.compute_operand_shapec                 C   s   |j dd  dkrtd|jtjd}d gd }||d< | g d|d< d gd }| ||d< | tj	|| |d |fS )Nr   )r   r   z1Automatic transpose only supported for H,W == 1,1)r   r   r   r   )
r   r   _replacer   r   r'  r   r5  r   r   )r   in_idr   out_operr   r   r   r   r   transpose_to_nhwc`  s    

z"_NnapiSerializer.transpose_to_nhwcc                 C   s   |j |j kr||||fS |j |j f}|tjtjfkrH| ||||f S |tjtjfkrl||f| || S td|j d|j d S )Nz2Automatic transpose not supported for dim_orders: z, )r   r   r   r   rH  r   )r   in0_idin0_operin1_idin1_operZordersr   r   r   transpose_for_broadcastt  s    z(_NnapiSerializer.transpose_for_broadcastc                 C   sL   |  |\}}| dkr2|  dks.J |S td|d|dd S )NListTypeIntTypezCan't handle size arg of type 'z' for 'r  )r0  r:  getElementTyper   r7  r   r   r   get_size_arg  s    z_NnapiSerializer.get_size_argc           	      C   s   dd |D }|d dksJ |d |d g}|d |d g}|d |d	 g}|d
 |d g}|d }t |dksvJ |ddgksJ | |||||S )Nc                 S   s   g | ]}|  qS r   )item.0r  r   r   r   
<listcomp>      zD_NnapiSerializer.get_conv_pool_args_2d_from_pack.<locals>.<listcomp>r   r   r   r   r   r	   r
   r   r   r   r   )r   get_conv_pool_args_2d_common)	r   kernel_sizepacked_configZpcstridespaddings	dilationsZoutput_padding	group_numr   r   r   get_conv_pool_args_2d_from_pack  s    
z0_NnapiSerializer.get_conv_pool_args_2d_from_packc                 C   s`   |  |}|  |}|d u r&ddg}n
|  |}|d urJ| |d\}	}
nd }
| |||||
S )Nr   rO  )rQ  r0  rW  )r   rX  stridepaddingdilationr   rZ  r[  r\  r   r]  r   r   r   get_conv_pool_args_2d_from_jit  s    




z/_NnapiSerializer.get_conv_pool_args_2d_from_jitc           
      C   sv   t |}t|dksJ t|dks(J t|dks8J t|dksHJ |\}}||||g}	t|| |	 | |g  S Nr   )r   r   r   )
r   rX  rZ  r[  r\  r]  ZkernelsphpwZreal_paddingsr   r   r   rW    s    z-_NnapiSerializer.get_conv_pool_args_2d_commonc               
   C   s  |  d |  d g }g }t|j }| || | ttt|j dd  |D ].\}\}}	| 	|||	}
|
| j|
 jj q\t|j D ] \}}td|| | | q|j }| dksJ | dksJ |d}dg}|  dkr|g}d}n8|  d	kr:| j| }t|}ntd
|  |d urlt|t|kslJ t|D ]d\}}| j| }
| j
|
 |
| j|
 jj |r|| nd }|
| |
| j|
 |d  qt|
d g }d}td|t| jt| jt| j t| jt| j}|
| | ! \}}|"dd | jD  |"| |"dd | j D  d#|g}t|d }|d dksJ t$|d }t| jD ]\}
\}}}}}t%||}t|D ]D\}}|dkr
t&||}| j'
d| dt(|
|  |d7 }qt)dd |D }|
| *| q|"| |
| *| j+ |
| *| j |
| *| j | j'"| t,,dd#|| j-||| j'|fS )NFTr   zProcessing node #%d: %rr   zreturn [r.  r=  Z	TupleTypezUnsupported return type: r?  r  Ziiiiiic                 s   s.   | ]&\}}}}}t d |t|||V  qdS )ZiifiN)r  r  r   )rT  tr   _mr+  zr   r   r   	<genexpr>  s   z3_NnapiSerializer.serialize_model.<locals>.<genexpr>c                 s   s    | ]}t jd g|R  V  qdS )r  N)r  r  )rT  xr   r   r   ri    rV  rV  r   z
ser_model[z] = c                 s   s   | ]}|d kr|ndV  qdS )r=  r   Nr   rT  r   r   r   r   ri    rV  r  ).r#  nextgraphr   r9  typer  r   r   r  r   r   r   r   nodesr   debugadd_nodeZreturn_node
inputsSizeoutputsSizeinputsAtr:  r   r   r   r   r   rB  r  r  r   r   serialize_valuesr3  rA  r   r   r   r   r   r   serialize_intsr   r%  r   ) r   modelr   return_shapesZinp_dim_ordersZout_dim_ordersZself_jitvalr  Zinput_valueZinput_tensorr   idxnodeZretnZ
retn_inputZtemplate_return_linesZreturn_valuesZretval_countr  vr   versionheaderserialized_valuesserialized_value_dataZmodel_offsetr   r   r   r   r+  Zpt_dr   r   r   serialize_model  s    








	






z _NnapiSerializer.serialize_modelc           	   	   C   s   g }g }t | jt | jks J t| j| jD ]T\\}}}t |}|d dB d }|d||   }|td||| || q.||fS )Nr   r   r"  r  )r   r   r   r   r   r  r  )	r   r~  r  Zop_indexZsource_typedataZsource_lengthZphysical_lengthZpadded_datar   r   r   ru  /  s    z!_NnapiSerializer.serialize_valuesc                 C   s   t  d|  S r$  )r%  r&  )intsr   r   r   rv  A  s    z_NnapiSerializer.serialize_intsc                 C   s
   |  |S r   )add_getattrr   rz  r   r   r   <lambda>F  rV  z_NnapiSerializer.<lambda>c                 C   s
   |  |S r   )add_constant_noder  r   r   r   r  G  rV  c                 C   s
   |  |S r   )add_list_constructr  r   r   r   r  H  rV  c                 C   s
   |  |S r   )add_tuple_constructr  r   r   r   r  I  rV  c                 C   s
   |  |S r   )add_unsqueezer  r   r   r   r  J  rV  c                 C   s
   |  |S r   )add_tor  r   r   r   r  K  rV  c                 C   s
   |  |S r   	_identityr  r   r   r   r  L  rV  c                 C   s
   |  |S r   )add_reshaper  r   r   r   r  M  rV  c                 C   s
   |  |S r   )add_flattenr  r   r   r   r  N  rV  c                 C   s
   |  |S r   )	add_slicer  r   r   r   r  O  rV  c                 C   s
   |  |S r   )add_sizer  r   r   r   r  P  rV  c                 C   s
   |  |S r   )add_catr  r   r   r   r  Q  rV  c                 C   s
   |  |S r   )add_meanr  r   r   r   r  R  rV  c                 C   s
   |  |S r   )add_quantizer  r   r   r   r  S  rV  c                 C   s
   |  |S r   )add_dequantizer  r   r   r   r  T  rV  c                 C   s   |  |tjtjS r   )add_add_sub_opr   rq   r   r   r  r   r   r   r  U  s   
c                 C   s   |  |tjtjS r   )r  r   r   r   r   r  r   r   r   r  X  s   
c                 C   s   |  |tjtjS r   )(add_pointwise_simple_binary_broadcast_opr   rz   r   r   r  r   r   r   r  [  s   
c                 C   s   |  |tjtjS r   )r  r   r   r   r   r  r   r   r   r  ^  s   
c                 C   s   |  |tjS r   )add_pointwise_simple_unary_opr   r{   r  r   r   r   r  a  s   c                 C   s   |  |tjS r   )r  r   rx   r  r   r   r   r  d  s   c                 C   s
   |  |S r   )add_softmaxr  r   r   r   r  g  rV  c                 C   s
   |  |S r   )add_hardtanhr  r   r   r   r  h  rV  c                 C   s
   |  |S r   )add_avg_pool2dr  r   r   r   r  i  rV  c                 C   s   |  |tjS r   )add_pool2d_noder   ry   r  r   r   r   r  j  s   c                 C   s
   |  |S r   )add_adaptive_avg_pool2dr  r   r   r   r  m  s   c                 C   s
   |  |S r   )add_upsample_nearest2dr  r   r   r   r  p  s   c                 C   s
   |  |S r   )add_prelu_opr  r   r   r   r  s  rV  c                 C   s
   |  |S r   )	add_addmmr  r   r   r   r  t  rV  c                 C   s
   |  |S r   )
add_linearr  r   r   r   r  u  rV  c                 C   s
   |  |S r   )add_conv_underscorer  r   r   r   r  v  rV  c                 C   s
   |  |S r   )
add_conv2dr  r   r   r   r  w  rV  c                 C   s
   |  |S r   )add_log_softmaxr  r   r   r   r  x  rV  c                 C   s
   |  |S r   )add_qlinearr  r   r   r   r  y  rV  c                 C   s   |  |tjS r   add_qconv2dr   r   r  r   r   r   r  z  s   c                 C   s   |  |tjS r   )r  r   r   r  r   r   r   r  }  s   c                 C   s   | j |tjddS )NT)r   r  r  r   r   r   r    s   c                 C   s   |  |tjtjS r   )add_qaddr   rq   r   r   r  r   r   r   r    s   
c                 C   s   |  |tjtjS r   )r  r   rq   r   r   r  r   r   r   r    s   
c                 C   s   |  |tjtjS r   )r  r   rz   r   r   r  r   r   r   r    s   
)(zprim::GetAttrzprim::Constantzprim::ListConstructzprim::TupleConstructzaten::unsqueezezaten::tozaten::detachzaten::reshapezaten::flattenzaten::slicez
aten::sizez	aten::catz
aten::meanzaten::quantize_per_tensorzaten::dequantizez	aten::addz	aten::subz	aten::mulz	aten::divz
aten::reluzaten::sigmoidzaten::softmaxzaten::hardtanhzaten::avg_pool2dzaten::max_pool2dzaten::adaptive_avg_pool2dzaten::upsample_nearest2dzaten::preluzaten::addmmzaten::linearzaten::_convolutionzaten::conv2dzaten::log_softmaxzquantized::linearzquantized::conv2dzquantized::conv2d_reluzquantized::conv_transpose2dzquantized::addzquantized::add_reluzquantized::mulc                 C   s:   | j | }|s,td| d||| | d S )NzUnsupported node kind (z
) in node )	ADDER_MAPr/  r:  r   )r   rz  Zadderr   r   r   rq    s    z_NnapiSerializer.add_nodec                 C   s,   |  |d\}}|d}|| j|< d S r   )r)  rt  	outputsAtr   )r   rz  rF  Z_in_operr   r   r   r   r    s    
z_NnapiSerializer._identityc                 C   s~   |  dksJ | dks J | |d\}}t|dsFJ |d}t||}|d}|	 }| 
||| d S )Nr   r   z
__torch__.name)rr  rs  r0  rt  r  
startswithr+  r
  r  rn  r9  )r   rz  Z	obj_ctypeobjr  r   outputr8  r   r   r   r    s    


z_NnapiSerializer.add_getattrc                 C   sL   |  dksJ | dks J |d}| }| }| ||| d S )Nr   r   )rr  rs  r  rn  ZtoIValuer9  )r   rz  r  r8  r   r   r   r   r    s    
z"_NnapiSerializer.add_constant_nodec           	      C   s   |  dksJ |d}| }g }g }| D ]\}|d urb|| jv rb| |\}}|| nd }|d ur|  dkr|| q2d }q2|d ur| ||| |d ur| 	|| |d u r|d u rt
d|d S )Nr   r   r.  zMUnable to handle ListConstruct node.  Neither all constants nor all tensors. )rs  r  rn  r   r   r0  r   r:  r9  r6  r   )	r   rz  r  r8  Z
const_valstensorsinpr   valr   r   r   r    s*    
z#_NnapiSerializer.add_list_constructc                 C   s6   |  dksJ |d}t| }| || d S )Nr   r   )rs  r  r   r   r6  )r   rz  r  r   r   r   r   r    s    
z$_NnapiSerializer.add_tuple_constructc                 C   s   |  dksJ | dks J | |d\}}| |dd\}}|jtjksZJ |dkrf|n|t|j	 d }t
|j	}||d t|}|j|d}	d gd }
||
d< | ||
d< d gd }| |d|	|d< | tj|
| d S )Nr   r   r   rO  r   )rr  rs  r,  rt  r0  r   r   r   r   r   r   insertr   rE  r  r   r  r5  r   r   )r   rz  rF  in_operr   r   Zreal_dimZout_shape_listr   rG  r   r   r   r   r   r    s     


z_NnapiSerializer.add_unsqueezec                 C   s   |  | d S r   r  r  r   r   r   r    s    z_NnapiSerializer.add_toc                 C   s  |  dksJ | dks J | |d\}}| |d\}}| dksXJ |  dkslJ t|dko|d dk}|jt	j
kr|stdtd|j|j}|j|t	j
d}d gd }	||	d< | ||	d< d gd }
| |d||
d< | tj|	|
 d S )	Nr   r   r   rN  rO  r=  zSCurrently, reshape is only supported on NHWC tensors if the target size is [X, -1].r   )rr  rs  r,  rt  r0  r:  rP  r   r   r   r   r   torchzerosexpandr   ZreshaperE  r'  r   r  r5  r   r~   )r   rz  rF  r  Zshape_ctyper   Zis_trivial_reshaper   rG  r   r   r   r   r   r    s*    

z_NnapiSerializer.add_reshapec              	   C   s,  |  dksJ | dks J | |d\}}| |dd\}}| |dd\}}t|jdko|jd dkp|jd dko|jd dk}|jtj	kr|st
d|dk r|t|j7 }|dk r|t|j7 }|jd | ttj|j||d  f |j|d d   }	tdd	 |j||d  D rDt
d
|jd | |j|d d   }
|
ddkr|t
d|j|	tj	d}| |d|}t|	D ],\}}|dkr| ||||jd qtdd	 |	D }d gd }||d< | ||d< d gd }||d< | tj|| d S )Nr   r   r   rO  r   r   zGCurrently, flatten is not supported on NHWC tensors unless C=1 or H=W=1c                 s   s   | ]}|d kV  qdS )r   Nr   rT  r   r   r   r   ri  (  rV  z/_NnapiSerializer.add_flatten.<locals>.<genexpr>z-Flattening flexible dims is not supported yetzOnly 1 dim can be flexibler   c                 s   s   | ]}|d kr|ndV  qdS )r   r=  Nr   r  r   r   r   ri  9  rV  )rr  rs  r)  rt  r0  r   r   r   r   r   r   	functoolsreduceoperatormulanycountrE  r   r  r  rC  r   r   r'  r5  r   r~   )r   rz  rF  r  Z_start_ctypeZ	start_dimZ
_end_ctypeZend_dimZis_trivial_flattenr   Znon_flattened_dimsrG  out_idry  r   Zinputs_1r   r   r   r   r   r    sV    (" 


z_NnapiSerializer.add_flattenc                    s  |  dksJ | dks J | |d\}}| |d\} | |d\}| |d\}| |d\}d u rdd u rtjdk r|j  7 ntjkrddkrtjkr| | d S |j  dkrt	ddk r|j  7 ntjkr*|j  kr<t	d  t
 fd	d
t|jD }| |d|j|d}d}t|D ]0\}}	|	dkr| |||| |d|> O }qd gd }
||
d< |  fddtt|jD |
d< |  fddt|jD |
d< |  fddtt|jD |
d< | d|
d< | ||
d< | d|
d< d gd }||d< | tj|
| d S )Nr	   r   r   r   r   r   z#Unable to slice with flexible shapez0Slice start value should be less than stop valuec                 3   s"   | ]\}}| krn|V  qd S r   r   rT  r  r   )	dim_valueout_lenr   r   ri  i  s   z-_NnapiSerializer.add_slice.<locals>.<genexpr>r  r   c                    s   g | ]}| krnd qS )r   r   rS  )r  start_valuer   r   rU  z  rV  z._NnapiSerializer.add_slice.<locals>.<listcomp>c                    s    g | ]\}}| krn|qS r   r   r  )r  
stop_valuer   r   rU  }  s   c                    s   g | ]}| krnd qS )r   r   rS  )r  
step_valuer   r   rU    rV  r
   )rr  rs  r)  rt  r0  sysmaxsizer   r  r   r   r  r   r  rE  rC  r'  ranger   r  r5  r   r   )r   rz  rF  r  r   r   r  Zend_maskry  r   r   r   r   )r  r  r  r  r  r   r  C  sv    







z_NnapiSerializer.add_slicec                 C   sr   |  dksJ | dks J | |d\}}| j|d \}}|j| }|d}| || | d S )Nr   r   r   )	rr  rs  r,  rt  r   r   r  r9  rn  )r   rz  r   r  r   resr  r   r   r   r    s    

z_NnapiSerializer.add_sizec                    s  |  dksJ | dks J | j|d }| |dd\} t|dksVJ g }d }d}|D ]}| |\}}	|d u rt|	j d}
|	j	|
d}|	j
|j
ksJ |	j|jksJ t|	j dt|j dksJ || ||	j  7 }qf|d usJ |j	t|j |d}|	jtjkrHt|jdks:J g d  }n }| |d|}t|jD ]Z\}}|dkrh| krd	 fd
d|D }| ||| n| |||d | qh|| |g }d gd }||d< | tj|| d S )Nr   r   r   rO  r=  r  r   r   r   r   r    + c                 3   s   | ]}t | V  qd S r   )r   )rT  Zip_idr   r   r   ri    rV  z+_NnapiSerializer.add_cat.<locals>.<genexpr>)rr  rs  r   rt  r0  r   r)  r   r   rE  r   r   r   r   r   r   r  r  rA  r  rC  r  r5  r   rs   )r   rz  r  r   Zin_idsrG  Zout_dim_sizer  rF  r  r   	nnapi_dimr  ry  r   r   r   r   r   r  r   r    sN    




z_NnapiSerializer.add_catc                 C   s  |  dksJ | dks J | |d\}}| |d\}}| dksXJ |  dkslJ | |dd\}}| |dd	 |jtj	krt
|jdksJ d
d |D }n|}t }	|D ]$}
|
dk r|
t
|j7 }
|	|
 q|jtj	kr&|s&|	ddhsJ tj}n|j}g }t|jD ]0\}}||	vrX|| n|r:|d q:|j||d}d gd }||d< | ||d< | ||d< d gd }| |d||d< | tj|| d S )Nr   r   r   rN  rO  r   ZBoolTyper   NoneTypec                 S   s   g | ]}g d | qS )r  r   rk  r   r   r   rU    rV  z-_NnapiSerializer.add_mean.<locals>.<listcomp>r   )rr  rs  r,  rt  r0  r:  rP  r   r   r   r   r   setadd
issupersetr   r  r   rE  r'  r  r   r  r5  r   r   )r   rz  rF  r  Z	dim_ctyper   r   Zkeep_dimr  Zcollapsed_dimsr   Zout_dim_orderr   r  r+  rG  r   r   r   r   r   r    sF    


z_NnapiSerializer.add_meanc                 C   s   |  dksJ | dks J | |d\}}|jtjkrHtd| |dd\}}| |dd\}}| |dd\}}|t	j
jkrtd	tj}|j|||d
}	d gd }
||
d< d gd }| |d|	|d< | tj|
| d S )Nr   r   r   zqMost hardware backends prefer NHWC quantized tensors.  Try setting `t.nnapi_nhwc = True` on your tensor inputs.  	FloatTyper   rO  r   zKPyTorch NNAPI export only supports quantized tensors with the quint8 dtype.r   r   r   )rr  rs  r,  rt  r   r   r   r   r0  r   r   r   r   r   rE  r   r  r5  r   r   )r   rz  rF  r  r   r   r   Zscalar_typer   rG  r   r   r   r   r   r    s2    

z_NnapiSerializer.add_quantizec                 C   s   |  dksJ | dks J | |d\}}|jtjddd}d gd }||d< d gd }| |d||d< | 	t
j|| d S )Nr   r   r   r  )rr  rs  r,  rt  rE  r   r   r   r  r5  r   rv   )r   rz  rF  r  rG  r   r   r   r   r   r     s    

z_NnapiSerializer.add_dequantizec                 C   s   |  dksJ | dks J | |d\}}|}|tjkr\|jtjkr\|j	ddd}| 
|d|}t|jD ] \}}|dkrx| |||| qxd gd }	||	d< d gd }
||
d< | ||	|
 d S )Nr   r   g      p?)r   r   )rr  rs  r)  rt  r   rx   r   r   r   rE  r   r  r  r   rC  r5  )r   rz  r4  rF  r  rG  r  ry  r   r   r   r   r   r   r  3  s     


z._NnapiSerializer.add_pointwise_simple_unary_opqparamsc             	   C   sF  |  dksJ |d  dks*J |d  dksDJ | |dr| |d\}}| |d|j\}}nN| |dr| |d\}}| |d|j\}}ntd| d|j	|j	ksJ | 
||||\}}}}t|j|j}	|j|	d}
|dur2|\}}|
j||d}
| |d|
}tt|j|jD ]\}\}}|dkr|dkr| |||| nn|dkr|dkr| |||| nH|dkrV|dkrV| jd	t|| d
t||  | |||| qVdgd }||d< ||d< | ||d< dgd }||d< | ||| dS )zFHelper for pointwise binary broadcast ops with superfluous extra args.r   r   r.  zCan't do a NNAPI binary op: z on two constantsr  Nr   r   zassert z == r   r   )rs  rt  rn  r:  r(  r)  r1  r   r   r   rM  r   r   rE  r   r  r  r   rC  r   r   r   r  r5  )r   rz  r4  	fuse_coder  rI  rJ  rK  rL  r   rG  r   Zzpr  ry  Zd0r   r   r   r   r   r   _do_add_binaryO  sV    





z_NnapiSerializer._do_add_binaryc                 C   s"   |  dksJ | ||| d S rc  )rr  r  )r   rz  r4  r  r   r   r   r    s    z9_NnapiSerializer.add_pointwise_simple_binary_broadcast_opc                 C   sH   |  dksJ | |dd\}}|dkr6td| ||| d S )Nr   r   rO  r   z*NNAPI does not support add/sub with alpha.)rr  r0  rt  r   r  )r   rz  r4  r  r   alphar   r   r   r    s    z_NnapiSerializer.add_add_sub_opc                 C   sV   |  dksJ | |dd\}}| |dd\}}| j|||||fd d S )Nr   r   r  r   rO  r  )rr  r0  rt  r  )r   rz  r4  r  r   r   r   r   r   r   r    s    z_NnapiSerializer.add_qaddc                 C   s   |  dksJ | |d\}}| |dd\}}| |d|}t|jD ] \}}|dkrV| |||| qVd gd }	||	d< | 	d|	d< | 
||	d< d gd }
||
d< | tj|	|
 d S )Nr   r   r   rO  g      ?r   )rr  r)  rt  r0  r   r  r  r   rC  r   r  r5  r   r   )r   rz  rF  r  r   Zsoftmax_dimr  r   r   r   r   r   r   r   r    s     

z_NnapiSerializer.add_softmaxc                 C   s   |  dksJ | dks J | |d\}}| |dd\}}| |dd\}}tjtjd}|||f}|d u rt	dd gd }	||	d< d gd }
| 
|d||
d< | ||	|
 d S )Nr   r   r   r  r   ))r=  r   )r   r
   z9NNAPI only supports hardtanh with args (-1, 1) or (0, 6).)rr  rs  r,  rt  r0  r   r|   r}   r/  r   r   r  r5  )r   rz  rF  r  r   Zmin_valZmax_valZop_mapr4  r   r   r   r   r   r    s$    

z_NnapiSerializer.add_hardtanhc                 C   sP  |  dksJ | dks J |d  dks:J |d  dksTJ | |d\}}| |d\}}t|jdksJ |jd dksJ |jd dkr|	 rt
d| |d|}t|jD ]4\}}|dkrq|dkrt
dq| |||| qd gd }	||	d< ||	d< d gd }
||
d< | tj|	|
 d S )Nr   r   r   r.  z8Per-channel PReLU only supports channels_last right now.z.PReLU requires fixed size for dim 0 and dim 1.)rr  rs  rt  rn  r:  r)  r2  r   r   r   r   r   r  r  rC  r5  r   r   )r   rz  rF  r  Zw_idZw_operr  r   r   r   r   r   r   r   r    s8    

z_NnapiSerializer.add_prelu_opc                 C   s  |  dksJ | dks J | \}}}}}}|p:|}| | ||||}	|	jdksf|	jdkrntd| |\}
}t	|j
dksJ t|j
|	|j
d d}| }d gd }|
|d< | |	j|d< | |	j|d< | |	j|d	< | |	j|d< | |	j|d
< | |	j|d< | |	j|d< | |	j|d< | tj|d< | ||d< d gd }| |d|j|d|d< | ||| d S )Nr
   r   z'NNAPI does not support dilated pooling.r   Fr   r   r   r   r	   r   r   r   r   r  )rr  rs  r   rb  rQ  r   r   r   r,  r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r#  r   r  rE  r5  )r   rz  r4  imagekernelr_  r`  ra  
_ceil_moder   image_id
image_operr   r   r   r   r   r   r   r    s@    

z _NnapiSerializer.add_pool2d_nodec                 C   s  |  dksJ | dks J | \}}}}}}}| |\}	}
| |\}	}|
rZ|rbtd| | |||}| |\}}t|j	dksJ t
|j	||j	d d}| }d gd }||d< | |j|d< | |j|d< | |j|d	< | |j|d< | |j|d
< | |j|d< | |j|d< | |j|d< | tj|d< | ||d< d gd }| |d|j|d}| |||d ||d< | tj|| d S )Nr   r   zANNAPI doesn't support count_include_pad=False or divisor_overrider   Fr   r   r   r   r	   r
   r   r   r   r  )rr  rs  r   r0  r   rb  rQ  r)  r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r#  r   r  rE   _handle_conv_pool_flexible_inputr5  r   rr   )r   rz  r  r  r_  r`  r  Zcount_include_padZdivisor_overrider   Zcount_include_pad_valueZdivisor_override_valuer   r  r  r   r   r   r   r  r   r   r   r     sZ    	

z_NnapiSerializer.add_avg_pool2dc           
      C   s  |  dksJ | dks J | |d\}}t|jdksFJ | |d\}}| dksjJ |  dks~J |ddgkrt	d|jdd t
| }| }d gd }||d< | d|d< | d|d< | d|d	< | d|d< | d|d
< | d|d< | |jd	 |d< | |jd |d< | tj|d< | ||d< d gd }	| |d|j|d|	d< | tj||	 d S )Nr   r   r   r   rN  rO  z@NNAPI only supports adaptive_avg_pool2d with output size (1, 1).r   r   r	   r
   r   r   r   r   r  )rr  rs  r,  rt  r   r   r0  r:  rP  r   r   r   r  r   r   r#  r   r  rE  r5  r   rr   )
r   rz  r  r  
size_ctypesize_argr   r   r   r   r   r   r   r  V  s@    

z(_NnapiSerializer.add_adaptive_avg_pool2dc                 C   s$  |  dks|  dksJ | dks,J |  dkrH| \}}}n| \}}}}| |\}}|  dkr| |\}	}
nD| |\}}| |\}}| dksJ | dksJ |}	|}
| |\}}t|jdksJ | dkr|	 dkrtdn| dkr| dks.J |	  dksDJ |	 dksVJ |
d u sdJ t
|tstJ |s~J tdd	 |D sJ t|dkr|d
 }t|d
ksJ |d }|d }| |}| |}n|	 dkr|	 dksJ |		  dksJ | dks.J |d u s<J t
|
tsLJ |
sVJ tdd	 |
D snJ t|
dkr|
d
 }
t|
d
ksJ t|
d |jd
  }t|
d |jd  }| |
d }| |
d }ntd|jd |jd ||f}| }| |d|j|d}|jd dksB|jd dkrJtddD ]~}|j| dkrN| dkr| ||||d
   nB|	 dkr| ||d|
|d
   dt|| d ntdqNd gd }||d< ||d< ||d
< | ||d< d gd }||d< | tj|| d S )Nr   r   r   r  z'Size and scale cannot both be non-None.rN  rO  c                 s   s   | ]}t |tV  qd S r   )r   r   rT  r  r   r   r   ri    rV  z:_NnapiSerializer.add_upsample_nearest2d.<locals>.<genexpr>r   r   r  c                 s   s   | ]}t |tV  qd S r   )r   r   r  r   r   r   ri    rV  z#Size and scale cannot both be None.r  z(Flexible batch or channels not supported)r   r   zint(z * r@  )rr  rs  r   r0  r:  r)  r   r   r   rP  r   r   allr  r   r   r   r   r  rE  r  r   r#  r5  r   r   )r   rz  r  Zsize_jitZ	scale_jitZscale_h_jitZscale_w_jitr  r  scale_ctypeZ	scale_argZscale_h_ctypeZscale_h_argZscale_w_ctypeZ_scale_w_argr  r  r   r   Zarg_hZarg_wr   r   r  r   r   r   r   r   r   r  ~  s    


 

z'_NnapiSerializer.add_upsample_nearest2dc           
      C   s   |  dksJ | dks J | \}}}}}||fD ]2}| |\}}	| dv s\J |	dkr:tdq:| |d||| d S )Nr	   r   )rO  r  z6NNAPI Fully-Connected does not support alpha and beta.T)rr  rs  r   r0  r:  r   add_addmm_or_linear)
r   rz  jit_bias	jit_input
jit_weightZjit_betaZ	jit_alphar   r  Zscale_valuer   r   r   r    s    z_NnapiSerializer.add_addmmc                 C   sD   |  dksJ | dks J | \}}}| |d||| d S )Nr   r   F)rr  rs  r   r  )r   rz  r  r  r  r   r   r   r    s    z_NnapiSerializer.add_linearc                 C   s4  |  |\}}| |\}}	t|jdks.J t|	jdks@J | |d\}
}t|jdksbJ |rt|  }n| }| |}| j| }|jd |jd f}| 	|
d|j|d}|jd dkr| |d|d d gd }||d< ||d< ||d< | tj|d< d gd }||d< | tj|| d S )Nr   r   r.  r   r  r   r   )r)  r2  r   r   r0  rf  
contiguousr  r   r   r  rE  rC  r  r   r   r5  r   rw   )r   rz  Ztranspose_weightr  r  r  input_id
input_operbias_id	bias_operr   weight_tensornnapi_weight_tensor	weight_idweight_operr   r  r   r   r   r   r   r    s2    



z$_NnapiSerializer.add_addmm_or_linearc                 C   sj  |  dksJ | dks J | \}}}}| |\}}t|jdksPJ | |d\}}	| |d\}}
| |\}}| dksJ | d \}}|d usJ t|jdksJ t|jdksJ |jd |jd ksJ |jd |jd ksJ |	 t
jksJ |jt
jkr&|}nB|jt
jks8J t
j|  d t
j| | d d	}| }|j| }t
||dt
j}| |}|j| |	 }|dksJ |dkrtd
| }| |}| j| }|jd |jd f}|j||	|
d}d gd }||d< ||d< ||d< | tj |d< d gd }| !|"d||d< | #t$j%|| d S )Nr   r   r   r  rO  ZLinearPackedParamsBaser      r  Quantized convolution multiplier is greater than 1.  This is supported by NNAPI, but not by most hardware backends.  Try training a model without quantization-aware training.  r   r   r   r   )&rr  rs  r   r,  r   r   r0  r  __getstate__qschemer  per_tensor_affiner  r   qint8!_make_per_tensor_quantized_tensorint_reprr   touint8r  r	  r   quantize_per_tensorr   r  r   r  r   rE  r  r   r   r   r  r5  r   rw   )r   rz  r  jit_packed_weight	jit_scalejit_zero_pointr  r  r   	out_scaleout_zero_pointweight_ctypepacked_weight
raw_weightraw_biasunsigned_weightweight_scale
bias_scaleint_biasr  
multiplierr  r  r  r   rG  r   r   r   r   r   r    sp    







z_NnapiSerializer.add_qlinearc           
      C   sh   |  |\}}| dkrZ|r"dnd}tj| | |jd}| |}| j| }	||	fS | |S d S )Nr  r   r   )r  )	r0  r:  r  r  r   r  r  r   r2  )
r   r  r  r   r8  _valueZbias_idxZnnapi_bias_tensorr  r  r   r   r   get_optional_biase  s    

z"_NnapiSerializer.get_optional_biasc                 C   s   |  dksJ | dks J | \}}}}}}}| |d\}	}
| ||
\}}| |
jdd ||||}| |ddd||
||dt	j
	S )	Nr   r   r.  r   r   r   r   Frr  rs  r   r0  r  rb  r   add_conv2d_commonr  r   r   )r   rz  	jit_imager  r  
jit_stridejit_padjit_dilation
jit_groupsr   r  r  
_bias_operr   r   r   r   r  r  s6    
z_NnapiSerializer.add_conv2dc                 C   s   |  dksJ | dks J | \}}}}}}}}	}
}	}	}	}	| |d\}	}| |\}	}| |||\}}| |jdd ||||
}| |ddd|||||t	j
	S )Nr   r   r.  r   r   r   r   r  )r   rz  r  r  r  r  r  r  Zjit_transposer   r  r  r   r  r  r   r   r   r   r    sD    z$_NnapiSerializer.add_conv_underscorec                 C   s   |  dksJ | dks J | \}}}| |\}}| |d\}}|j}	d gd }
||
d< | d|
d< | ||
d< d gd }| |	d|j
|	d|d< | tj|
| d S )Nr   r   rO  r   r   r  )rr  rs  r   r,  r0  r   r   r  r   r  rE  r5  r   r   )r   rz  r  Zjit_dimZ_jit_half_to_floatr  r  r   r   r   r   r   r   r   r   r    s    

z _NnapiSerializer.add_log_softmaxc                 C   s  |  dksJ | dks J | \}}}}| |d\}}	| |d\}}
| |\}}| dksnJ | d \}}}|dksJ |\}}|\}|d usJ | |jdd |}| t	j
ksJ |jt	jkr|}n@|jt	jksJ t	j|  d	 t	j| | d	 d
}| }| |\}}|j| }t	||dt	j}| |}|j| |	 }|dksxJ |dkrtd| |d|	|
||||||	S )Nr   r   r  rO  ZConv2dPackedParamsBaser   2r   r  r  r  )rr  rs  r   r0  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   rz  r  r   r  r  r  r  r   r   r  r  r  Zpack_versionr  Zopt_tensorsrY  r  r  r   r  r  r  r  r	  r  r
  r   r   r   r    sn    




z_NnapiSerializer.add_qconv2dc
           !      C   s<  |  |\}
}|jd }|jdkr6d}|r0d}qRd}n|j|krJd}d}ntd|j|  }| |}| j| }| j| }|jt	j
kr|jt	j
ksJ |jt	j
ksJ nh|jt	jkr|jt	jksJ |jt	jksJ t|j|j |jsJ |jdksJ ntd|j t|jd	ks(J t|jd	ks<J t|jdksPJ |r|j\}}}}|dksrJ || dksJ || }|dksJ ||ksJ n|j\}}}}||ksJ ||jd ksJ | }|rd
}tj}nd}|rtj}ntj}d g| }|
|d< ||d< ||d< | |j|d< | |j|d	< | |j|d< | |j|d< | |j|d< | |j|d< |r| d|d< | |	|d< | ||d< n| |	|d< | ||d< d gd }t|j|||}|j|||d}|  ||} | !| ||| | |d< | "||| d S )Nr   F)r   r   r   r   r   Tz$Group convolution not supported yet.r   z#Unsupported input type for conv2d: 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   ru   r   rt   r  r   r   r   r   r   r   r#  r   rE  r   r  r5  )!r   Zjit_outr   r  r  r  r  r   r   r  r  r  Zin_cZ	depthwiseZweight_permutationr  r  r  r  ZoneZ_kern_hZ_kern_wZout_cZchannel_multiplierZkern_dr   num_argsr4  r   r   r   rG  r  r   r   r   r    s    








z"_NnapiSerializer.add_conv2d_commonc                 C   s^  |  |\}}|j\}}}	}
|dkr4| |d|d |dkrDtd|r|	dkr| |ddt|d d|j d|j d|j d|j	 
 |
dkr| |ddt|d d|j
 d|j d|j d|j 
 n|	dkr| |ddt|d d|j d|j d|j	 d	|j d
 |
dkrZ| |ddt|d d|j d|j d|j d	|j
 d
 d S )Nr   z Input channels can't be flexibler   r<  z - 1) * r  z - r   z) // z + 1)r)  r   rC  r   r  r   r   r   r   r   r   r   r   r   )r   r  r  r   r   r  r  r   Zin_chr   r   r   r   r   r    s>    ..
0
0z1_NnapiSerializer._handle_conv_pool_flexible_input)F)N)N)NN)N)F)F)Pr   r   r   r   r   r   r   r  r  r   r   r  r  r  r   r#  r'  r(  r)  r,  r   r1  r2  r5  r6  r9  r0  rB  rC  r  rH  rM  rQ  r^  rb  rW  r  ru  staticmethodrv  r  rq  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   F  s   
1

	

3	 

p
I8K
51"7&+6(b&I
 '
Aor   F)r   rx  r   c                C   s   t ||| ||S )a  Convert to NNAPI and serialize torchscript module.

    Parameters:
        module: Torchscript module to convert
        inputs: Tensors used to specify input details for NNAPI
        config (optional): Optional config to attach to module
        return_shapes (optional): Specify shape of outputs if
            your module uses runtime flexible shapes to set output
            buffer size for NNAPI
        use_int16_for_qint16 (optional): Use Pytorch int16 to represent NNAPI qint16 values
    )r   r  )moduler   r   rx  r   r   r   r   r    s    
r  )r   ) r%  enumr  loggingr  r  r  typingr   r   r  	getLoggerr   r   r   r   r   Enumr   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   <module>   sT   
b

 !              m