U
    +-e=                    @   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mZmZ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)List
NamedTupleOptionalTupleZ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   a/var/www/html/Darija-Ai-Train/env/lib/python3.8/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krdS | j tjk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tt |dks t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 )lenAssertionErrorr   r   zipappendr   )Zshape1Zshape2s1s2retd1Zd2r   r   r   broadcast_shapes   s$    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batch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kr| S |t jkr@t| d gt| dd   | d g S |t jkrjt| dksft| dksft| S |t jk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   r   	fix_shape  s    

(

r   c                 C   s2   | t jt jfkr|S | t jks"tddddg| S )Nr   r   r	   r   )r   r   r   r   r   )r   r   r   r   r   reverse_map_dim-  s    r   c                 C   s   d|  d| S )NZs__r   )op_iddimr   r   r   	flex_name8  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 k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__?  s$    z_NnapiSerializer.__init__c                 C   s
   t | jS r   )r   r   r   r   r   r   get_next_operand_idU  s    z$_NnapiSerializer.get_next_operand_idc                 C   sH   t |tst|| jkr&td||  }| j| || j|< |S )NzDuplicate tensor: )
isinstancer   r   r   r   r   r   r   )r   jitvaloper
operand_idr   r   r   add_tensor_operand[  s    

z#_NnapiSerializer.add_tensor_operandc                 C   s&   t |tst|  }| j| |S r   )r   r   r   r   r   r   )r   r   r   r   r   r   add_anonymous_tensor_operandh  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st	nn|d	kr| j
rt|d
d }tjtjf}||kr|}|j}|j}qtd| dqtdntd|j dtt|j||||dS )Nztorch.         r   Zfloat32Zint32quint8qint32Z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   r   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_operandn  sP    

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}|d dB d }| j|tj	f t| j
}d}| jtd||| |tjkr|dddd}| j
| |S )Nr   r	   r   iiir   )r  r   r   r   r   r   r   r   r   r   r   r   structpackr   r   permute)	r   r  r   r  r   ZtsizepsizeZbuf_numoffsetr   r   r   add_tensor_operand_for_weight  s    


z._NnapiSerializer.add_tensor_operand_for_weightc                 C   sv   t |tst||f}|| jk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   )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 k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 k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.  )r1  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 kst|| j |< d S r   )r   r   )r   r   r   r   r   r   add_tensor_sequence  s    z$_NnapiSerializer.add_tensor_sequencec                 C   s    || j kst||f| j |< d S r   )r   r   r   r   ctyper   r   r   r   add_constant_value	  s    z#_NnapiSerializer.add_constant_valueNc                 C   sd   | j |}|d kr$td|d|\}}|d k	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   r0  r   kind)r   r   Ztypekindrecordr9  r   r   r   r   r1    s    z#_NnapiSerializer.get_constant_valuec                 C   sH  |dkr|j }nt|t|j ks&t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k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   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  s@    

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_shapeG  s    z&_NnapiSerializer.forward_operand_shapec                 C   s    | j t|| d|  d S )Nz = )r   r   r   )r   r   r   exprr   r   r   r  J  s    z&_NnapiSerializer.compute_operand_shapec                 C   s   |j dd  dkrtd|jtjd}d gd }||d< | ddddg|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   r6  r    r   )r   in_idr   out_operr   r   r   r   r   transpose_to_nhwcO  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   rI  r   )r   in0_idin0_operin1_idin1_operZordersr   r   r   transpose_for_broadcasta  s    z(_NnapiSerializer.transpose_for_broadcastc                 C   sL   |  |\}}| dkr2|  dks.t|S td|d|dd S )NListTypeIntTypezCan't handle size arg of type 'z' for 'r  )r1  r;  getElementTyper   r   r8  r   r   r   get_size_argp  s
    z_NnapiSerializer.get_size_argc           	      C   s   dd |D }|d dkst |d |d g}|d |d g}|d |d	 g}|d
 |d g}|d }t|dksvt |ddgkst | |||||S )Nc                 S   s   g | ]}|  qS r   )item.0r  r   r   r   
<listcomp>x  s     zD_NnapiSerializer.get_conv_pool_args_2d_from_pack.<locals>.<listcomp>r   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_packw  s         z0_NnapiSerializer.get_conv_pool_args_2d_from_packc                 C   s`   |  |}|  |}|d kr&ddg}n
|  |}|d k	rJ| |d\}	}
nd }
| |||||
S )Nr   rP  )rR  r1  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tt|dks(tt|dks8tt|dksHt|\}}||||g}	t|| |	 | |g  S Nr   )r   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st| dkst|d}dg}|  dkr|g}d}n8|  d	kr:| j| }t|}ntd
|  |d k	rlt|t|kslt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st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   )rU  tr   _mr,  zr   r   r   	<genexpr>  s    z3_NnapiSerializer.serialize_model.<locals>.<genexpr>c                 s   s   | ]}t jd| V  qdS )r  N)r  )r  r  )rU  xr   r   r   ri    s         r
   z
ser_model[z] = c                 s   s   | ]}|d kr|ndV  qdS )r>  r   Nr   rU  r   r   r   r   ri    s     r  )/r$  nextgraphr   r:  typer  r   r   r  r   r   r   r   Znodesr   debugadd_nodeZreturn_node
inputsSizer   outputsSizeinputsAtr;  r   r   r   r   r   rC  r  r  r   r   serialize_valuesr4  rB  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 t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~  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'  )Zintsr   r   r   rv  *  s    z_NnapiSerializer.serialize_intsc                 C   s
   |  |S r   )add_getattrr   rz  r   r   r   <lambda>/  rk  z_NnapiSerializer.<lambda>c                 C   s
   |  |S r   )add_constant_noder  r   r   r   r  0  rk  c                 C   s
   |  |S r   )add_list_constructr  r   r   r   r  1  rk  c                 C   s
   |  |S r   )add_tuple_constructr  r   r   r   r  2  rk  c                 C   s
   |  |S r   )add_unsqueezer  r   r   r   r  3  rk  c                 C   s
   |  |S r   )add_tor  r   r   r   r  4  rk  c                 C   s
   |  |S r   	_identityr  r   r   r   r  5  rk  c                 C   s
   |  |S r   )add_reshaper  r   r   r   r  6  rk  c                 C   s
   |  |S r   )add_flattenr  r   r   r   r  7  rk  c                 C   s
   |  |S r   )	add_slicer  r   r   r   r  8  rk  c                 C   s
   |  |S r   )add_sizer  r   r   r   r  9  rk  c                 C   s
   |  |S r   )add_catr  r   r   r   r  :  rk  c                 C   s
   |  |S r   )add_meanr  r   r   r   r  ;  rk  c                 C   s
   |  |S r   )add_quantizer  r   r   r   r  <  rk  c                 C   s
   |  |S r   )add_dequantizer  r   r   r   r  =  rk  c                 C   s   |  |tjtjS r   )add_add_sub_opr    rs   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  A  s     c                 C   s   |  |tjtjS r   )(add_pointwise_simple_binary_broadcast_opr    r|   r   r   r  r   r   r   r  D  s     c                 C   s   |  |tjtjS r   )r  r    r   r   r   r  r   r   r   r  G  s     c                 C   s   |  |tjS r   )add_pointwise_simple_unary_opr    r}   r  r   r   r   r  J  s    c                 C   s   |  |tjS r   )r  r    rz   r  r   r   r   r  M  s    c                 C   s
   |  |S r   )add_softmaxr  r   r   r   r  P  rk  c                 C   s
   |  |S r   )add_hardtanhr  r   r   r   r  Q  rk  c                 C   s
   |  |S r   )add_avg_pool2dr  r   r   r   r  R  rk  c                 C   s   |  |tjS r   )add_pool2d_noder    r{   r  r   r   r   r  S  s    c                 C   s
   |  |S r   )add_adaptive_avg_pool2dr  r   r   r   r  V  s   c                 C   s
   |  |S r   )add_upsample_nearest2dr  r   r   r   r  Y  s   c                 C   s
   |  |S r   )add_prelu_opr  r   r   r   r  \  rk  c                 C   s
   |  |S r   )	add_addmmr  r   r   r   r  ]  rk  c                 C   s
   |  |S r   )
add_linearr  r   r   r   r  ^  rk  c                 C   s
   |  |S r   )add_conv_underscorer  r   r   r   r  _  rk  c                 C   s
   |  |S r   )
add_conv2dr  r   r   r   r  `  rk  c                 C   s
   |  |S r   )add_log_softmaxr  r   r   r   r  a  rk  c                 C   s
   |  |S r   )add_qlinearr  r   r   r   r  b  rk  c                 C   s   |  |tjS r   add_qconv2dr   r   r  r   r   r   r  c  s    c                 C   s   |  |tjS r   )r  r   r   r  r   r   r   r  f  s    c                 C   s   | j |tjddS )NT)r   r  r  r   r   r   r  i  s     c                 C   s   |  |tjtjS r   )add_qaddr    rs   r   r   r  r   r   r   r  l  s     c                 C   s   |  |tjtjS r   )r  r    rs   r   r   r  r   r   r   r  o  s     c                 C   s   |  |tjtjS r   )r  r    r|   r   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_MAPr0  r;  r   )r   rz  Zadderr   r   r   rq  w  s    z_NnapiSerializer.add_nodec                 C   s,   |  |d\}}|d}|| j|< d S r   )r*  rt  	outputsAtr   )r   rz  rG  in_operr   r   r   r   r  }  s    
z_NnapiSerializer._identityc                 C   s~   |  dkst| dks t| |d\}}t|dsFt|d}t||}|	d}|
 }| ||| d S )Nr   r   z
__torch__.name)rr  r   rs  r1  rt  r  
startswithr,  r
  r  ro  r:  )r   rz  Z	obj_ctypeobjr  r   outputr9  r   r   r   r    s    


z_NnapiSerializer.add_getattrc                 C   sL   |  dkst| dks t|d}| }| }| ||| d S )Nr   r   )rr  r   rs  r  ro  ZtoIValuer:  )r   rz  r  r9  r   r   r   r   r    s    
z"_NnapiSerializer.add_constant_nodec           	      C   s   |  dkst|d}| }g }g }| D ]\}|d k	rb|| jkrb| |\}}|| nd }|d k	r|  dkr|| q2d }q2|d k	r| 	||| |d k	r| 
|| |d kr|d krtd|d S )Nr   r   r/  zMUnable to handle ListConstruct node.  Neither all constants nor all tensors. )rs  r   r  ro  r   r   r1  r   r;  r:  r7  r   )	r   rz  r  r9  Z
const_valstensorsinpr   valr   r   r   r    s*    
z#_NnapiSerializer.add_list_constructc                 C   sF   |  dkst|d}g }| D ]}|| q&| || d S )Nr   r   )rs  r   r  r   r   r7  )r   rz  r  r   r  r   r   r   r    s    
z$_NnapiSerializer.add_tuple_constructc                 C   s   |  dkst| dks t| |d\}}| |dd\}}|jtjksZt|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   rP  r   )rr  r   rs  r-  rt  r1  r   r   r   r   r   r   insertr   rF  r  r   r  r6  r    r   )r   rz  rG  r  r   r   Zreal_dimZout_shape_listr   rH  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t| dks t| |d\}}| |d\}}| dksXt|  dkslt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   rO  rP  r>  zSCurrently, reshape is only supported on NHWC tensors if the target size is [X, -1].r   )rr  r   rs  r-  rt  r1  r;  rQ  r   r   r   r   r   torchzerosexpandr   ZreshaperF  r(  r   r  r6  r    r   )r   rz  rG  r  Zshape_ctyper   Zis_trivial_reshaper   rH  r   r   r   r   r   r    s,     

z_NnapiSerializer.add_reshapec              	   C   s.  |  dkst| dks t| |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dd	 |j||d  f |j|d d   }	td
d |j||d  D rFt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   rP  r   r
   zGCurrently, flatten is not supported on NHWC tensors unless C=1 or H=W=1c                 S   s   | | S r   r   )rj  yr   r   r   r    rk  z._NnapiSerializer.add_flatten.<locals>.<lambda>c                 s   s   | ]}|d kV  qdS )r   Nr   rU  r   r   r   r   ri    s     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  $  s     )rr  r   rs  r*  rt  r1  r   r   r   r   r   r   	functoolsreduceanycountrF  r   r  r  rD  r   r   r(  r6  r    r   )r   rz  rG  r  Zstart_ctypeZ	start_dimZ	end_ctypeZend_dimZis_trivial_flattenr   Znon_flattened_dimsrH  out_idry  r   Zinputs_1r   r   r   r   r   r    s\    ( 
"  


z_NnapiSerializer.add_flattenc                    s  |  dkst| dks t| |d\}}| |d\} | |d\}| |d\}| |d\}d krdd k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   rU  r  r   )	dim_valueout_lenr   r   ri  R  s    z-_NnapiSerializer.add_slice.<locals>.<genexpr>r  r   c                    s   g | ]}| krnd qS )r   r   rT  )r  start_valuer   r   rV  c  s     z._NnapiSerializer.add_slice.<locals>.<listcomp>c                    s    g | ]\}}| krn|qS r   r   r  )r  
stop_valuer   r   rV  f  s   c                    s   g | ]}| krnd qS )r   r   rT  )r  
step_valuer   r   rV  l  s     r   )rr  r   rs  r*  rt  r1  sysmaxsizer   r  r   r   r  r   r  rF  rD  r(  ranger   r  r6  r    r   )r   rz  rG  r  r   r   r  Zend_maskry  r   r   r   r   )r  r  r  r  r  r   r  .  st    




 



z_NnapiSerializer.add_slicec                 C   sr   |  dkst| dks t| |d\}}| j|d \}}|j| }|d}| ||	 | d S )Nr   r   r   )
rr  r   rs  r-  rt  r   r   r  r:  ro  )r   rz  r   r  r   resr  r   r   r   r  w  s    

z_NnapiSerializer.add_sizec                    s  |  dkst| dks t| j|d }| |dd\} t|dksVtg }d }d}|D ]}| |\}}	|d krt|	j	 d}
|	j
|
d}|	j|jkst|	j|jkstt|	j	 dt|j	 dkst|| ||	j	  7 }qf|d k	st|j
t|j	 |d}|	jtjkrLt|j	dks:tddddg  }n }| |d|}t|j	D ]Z\}}|dkrl| krd	 fd
d|D }| ||| n| |||d | ql|| |g }d gd }||d< | tj|| d S )Nr   r   r   rP  r>  r  r
   r	    + c                 3   s   | ]}t | V  qd S r   )r   )rU  Zip_idr   r   r   ri    s     z+_NnapiSerializer.add_cat.<locals>.<genexpr>)rr  r   rs  r   rt  r1  r   r*  r   r   rF  r   r   r   r   r   r   r  r  rB  r  rD  r  r6  r    ru   )r   rz  r  r   Zin_idsrH  Zout_dim_sizer  rG  r  r   	nnapi_dimr  ry  r   r   r   r   r   r  r   r    sR      




z_NnapiSerializer.add_catc                 C   s  |  dkst| dks t| |d\}}| |d\}}| dksXt|  dkslt| |dd\}}| |dd	 |jt	j
krt|jdkstd
d |D }n|}t }	|D ]$}
|
dk r|
t|j7 }
|	|
 q|jt	j
kr&|s&|	ddhstt	j}n|j}g }t|jD ]0\}}||	k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   rO  rP  r   ZBoolTyper	   NoneTypec                 S   s   g | ]}d dddg| qS )r   r	   r   r   r   rl  r   r   r   rV    s     z-_NnapiSerializer.add_mean.<locals>.<listcomp>r   )rr  r   rs  r-  rt  r1  r;  rQ  r   r   r   r   r   setadd
issupersetr   r  r   rF  r(  r  r   r  r6  r    r   )r   rz  rG  r  Z	dim_ctyper   r   Zkeep_dimr  Zcollapsed_dimsr   Zout_dim_orderr   r  r,  rH  r   r   r   r   r   r    sF    


z_NnapiSerializer.add_meanc                 C   s   |  dkst| dks t| |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   rP  r	   zKPyTorch NNAPI export only supports quantized tensors with the quint8 dtype.r   r   r   )rr  r   rs  r-  rt  r   r   r   r   r1  r   r   r   r   r   rF  r   r  r6  r    r   )r   rz  rG  r  r   r   r   Zscalar_typer   rH  r   r   r   r   r   r    s2    

z_NnapiSerializer.add_quantizec                 C   s   |  dkst| dks t| |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  r   rs  r-  rt  rF  r   r   r   r  r6  r    rx   )r   rz  rG  r  rH  r   r   r   r   r   r  	  s    

z_NnapiSerializer.add_dequantizec                 C   s   |  dkst| dks t| |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  r   rs  r*  rt  r    rz   r   r   r   rF  r   r  r  r   rD  r6  )r   rz  r5  rG  r  rH  r  ry  r   r   r   r   r   r   r    s     


z._NnapiSerializer.add_pointwise_simple_unary_opqparamsc             	   C   sF  |  dkst|d  dks*t|d  dksDt| |dr| |d\}}| |d|j\}}nN| |dr| |d\}}| |d|j\}}nt	d| d|j
|j
kst| ||||\}}}}t|j|j}	|j|	d}
|dk	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 )zEHelper for pointwise binary broadcast ops with superfluous extra argsr   r   r/  zCan't do a NNAPI binary op: z on two constantsr  Nr   r   zassert z == r	   r   )rs  r   rt  ro  r;  r)  r*  r2  r   r   r   rN  r   r   rF  r   r  r  r   rD  r   r   r   r  r6  )r   rz  r5  	fuse_coder  rJ  rK  rL  rM  r   rH  r   Zzpr  ry  Zd0r   r   r   r   r   r   _do_add_binary8  s\     
 
   


z_NnapiSerializer._do_add_binaryc                 C   s"   |  dkst| ||| d S rc  )rr  r   r  )r   rz  r5  r  r   r   r   r  m  s    z9_NnapiSerializer.add_pointwise_simple_binary_broadcast_opc                 C   sH   |  dkst| |dd\}}|dkr6td| ||| d S )Nr	   r   rP  r   z*NNAPI does not support add/sub with alpha.)rr  r   r1  rt  r   r  )r   rz  r5  r  r   alphar   r   r   r  q  s
    z_NnapiSerializer.add_add_sub_opc                 C   sV   |  dkst| |dd\}}| |dd\}}| j|||||fd d S )Nr
   r   r  r	   rP  r  )rr  r   r1  rt  r  )r   rz  r5  r  r   r   r   r   r   r   r  z  s    z_NnapiSerializer.add_qaddc                 C   s   |  dkst| |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   rP  g      ?r   )rr  r   r*  rt  r1  r   r  r  r   rD  r!  r  r6  r    r   )r   rz  rG  r  r   Zsoftmax_dimr  r   r   r   r   r   r   r   r    s     

z_NnapiSerializer.add_softmaxc                 C   s   |  dkst| dks t| |d\}}| |dd\}}| |dd\}}tjtjd}|	||f}|d k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  r   rs  r-  rt  r1  r    r~   r   r0  r   r   r  r6  )r   rz  rG  r  r   Zmin_valZmax_valZop_mapr5  r   r   r   r   r   r    s     

z_NnapiSerializer.add_hardtanhc                 C   sP  |  dkst| dks t|d  dks:t|d  dksTt| |d\}}| |d\}}t|j	dkst|j	d dkst|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  r   rs  rt  ro  r;  r*  r3  r   r   r   r   r   r  r  rD  r6  r    r   )r   rz  rG  r  Zw_idZw_operr  r   r   r   r   r   r   r   r    s4    


z_NnapiSerializer.add_prelu_opc                 C   s  |  dkst| dks t| \}}}}}}|p:|}| | ||||}	|	jdksf|	jdkrntd| 	|\}
}t
|jdkst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  r   rs  r   rb  rR  r   r   r   r-  r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r$  r   r  rF  r6  )r   rz  r5  imagekernelr_  r`  ra  	ceil_moder   image_id
image_operr   r   r   r   r   r   r   r    sN          

 
z _NnapiSerializer.add_pool2d_nodec                 C   s  |  dkst| dks t| \}}}}}}}| |\}	}
| |\}	}|
rZ|rbtd| | |||}| |\}}t	|j
dkst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  r   rs  r   r1  r   rb  rR  r*  r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r$  r   r  rF   _handle_conv_pool_flexible_inputr6  r    rt   )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    sf    	     

 
z_NnapiSerializer.add_avg_pool2dc           
      C   s  |  dkst| dks t| |d\}}t|jdksFt| |d\}}| dksjt|	  dks~t|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
   rO  rP  z@NNAPI only supports adaptive_avg_pool2d with output size (1, 1).r   r	   r   r   r   r   r   r   r  )rr  r   rs  r-  rt  r   r   r1  r;  rQ  r   r   r   r  r   r   r$  r   r  rF  r6  r    rt   )
r   rz  r  r  
size_ctypesize_argr   r   r   r   r   r   r   r  7  sB    

 
z(_NnapiSerializer.add_adaptive_avg_pool2dc                 C   s$  |  dks|  dkst| dks,t|  dkrH| \}}}n| \}}}}| |\}}|  dkr| |\}	}
nD| |\}}| |\}}| dkst| dkst|}	|}
| |\}}t|jdkst| dkr|	 dkrt	dn| dkr| dks.t|
  dksDt|	 dksVt|
d ksdtt|tstt|s~ttdd	 |D stt|dkr|d
 }t|d
kst|d }|d }| |}| |}n|	 dkr|	 dkst|	
  dkst| dks.t|d ks<tt|
tsLt|
sVttdd	 |
D sntt|
dkr|
d
 }
t|
d
kst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.rO  rP  c                 s   s   | ]}t |tV  qd S r   )r   r   rU  r  r   r   r   ri    s     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    s     z#Size and scale cannot both be None.r  z(Flexible batch or channels not supported)r   r	   zint(z * rA  )rr  r   rs  r   r1  r;  r*  r   r   r   rQ  r   r   allr  r   r!  r   r   r  rF  r  r   r$  r6  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t| dks t| \}}}}}||fD ]2}| |\}}	| dks\t|	dkr:tdq:| |d||| d S )Nr   r   )rP  r  z6NNAPI Fully-Connected does not support alpha and beta.T)rr  r   rs  r   r1  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t| dks t| \}}}| |d||| d S )Nr	   r   F)rr  r   rs  r   r  )r   rz  r  r  r  r   r   r   r    s    z_NnapiSerializer.add_linearc                 C   s4  |  |\}}| |\}}	t|jdks.tt|	jdks@t| |d\}
}t|jdksbt|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*  r3  r   r   r   r1  rf  
contiguousr  r   r   r  rF  rD  r  r   r   r6  r    ry   )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    s4    

 


z$_NnapiSerializer.add_addmm_or_linearc                 C   sj  |  dkst| dks t| \}}}}| |\}}t|jdksPt| |d\}}	| |d\}}
| |\}}| dkst|	 d \}}|d k	stt|jdkstt|jdkst|jd |jd kst|jd |jd kst|
 tjkst|jtjkr&|}nB|jtjks8ttj|  d tj| | d d	}| }|j| }t||dtj}| |}|j| |	 }|dkst|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  rP  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  r   rs  r   r-  r   r   r1  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   rF  r  r   r   r   r  r6  r    ry   )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   rH  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  )	r1  r;  r  r  r   r  r  r   r3  )
r   r  r  r   r9  r   Zbias_idxZnnapi_bias_tensorr  r  r   r   r   get_optional_biasD  s    
 

z"_NnapiSerializer.get_optional_biasc                 C   s   |  dkst| dks t| \}}}}}}}| |d\}	}
| ||
\}}| |
jdd ||||}| |	ddd||
||dt
j	S )	Nr   r   r/  r   r
   r   r   Frr  r   rs  r   r1  r  rb  r   add_conv2d_commonr  r   r   )r   rz  	jit_imager  r  
jit_stridejit_padjit_dilation
jit_groupsr   r  r  r  r   r   r   r   r  Q  s>    
    z_NnapiSerializer.add_conv2dc                 C   s   |  dkst| dks t| \}}}}}}}}	}
}	}	}	}	| |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  q  sL        z$_NnapiSerializer.add_conv_underscorec                 C   s   |  dkst| dks t| \}}}| |\}}| |d\}}|j}	d gd }
||
d< | d|
d< | ||
d< d gd }| 	|
d|j|	d|d< | tj|
| d S )Nr	   r   rP  r   r   r  )rr  r   rs  r   r-  r1  r   r!  r  r   r  rF  r6  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t| dks t| \}}}}| |d\}}	| |d\}}
| |\}}| dksnt| d \}}}|dkst|\}}|\}|d k	st| |jdd |}|	 t
jkst|jt
jkr|}n@|jt
jkstt
j|  d	 t
j| | d	 d
}| }| |\}}|j| }t
||dt
j}| |}|j| |	 }|dksxt|dkrtd| |d|	|
||||||	S )Nr
   r   r  rP  ZConv2dPackedParamsBaser   2r   r  r  r  )rr  r   rs  r   r1  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    sp    
 



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st|jt	j
kstnh|jt	jkr|jt	jkst|jt	jkstt|j|j |jst|jdkstntd|j t|jd	ks(tt|jd	ks<tt|jdksPt|r|j\}}}}|dksrt|| dkst|| }|dkst||kstn|j\}}}}||kst||jd kst| }|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   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   r    rw   r   rv   r  r   r   r   r   r   r   r$  r   rF  r   r  r6  )!r   Zjit_outr  r  r  r  r  r   r   r  r  r  r   Z	depthwiseZweight_permutationr  r  r  r  oneZkern_hZkern_wZout_cZchannel_multiplierZkern_dr   num_argsr5  r   r   r   rH  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   rD  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   r2  r3  r6  r7  r:  r1  rC  rD  r  rI  rN  rR  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   >  s   
/

	

/   

n
I:I
51"5	$+6(`&I
 '
Amr   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  typingr   r   r   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>   sV   
b

               R  