o
    ei
                    @   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Optional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INT32UINT32TENSOR_FLOAT32TENSOR_INT32TENSOR_QUANT8_ASYMMBOOLTENSOR_QUANT16_SYMMTENSOR_FLOAT16TENSOR_BOOL8FLOAT16TENSOR_QUANT8_SYMM_PER_CHANNELTENSOR_QUANT16_ASYMM r"   r"   j/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/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_2DDEPTH_TO_SPACE
DEQUANTIZEEMBEDDING_LOOKUPFLOORFULLY_CONNECTEDHASHTABLE_LOOKUPL2_NORMALIZATION
L2_POOL_2DLOCAL_RESPONSE_NORMALIZATIONLOGISTICLSH_PROJECTIONLSTMMAX_POOL_2DMULRELURELU1RELU6RESHAPERESIZE_BILINEARRNNSOFTMAXSPACE_TO_DEPTHSVDFTANHBATCH_TO_SPACE_NDDIVMEANPADSPACE_TO_BATCH_NDSQUEEZESTRIDED_SLICESUB	TRANSPOSEABSARGMAXARGMINAXIS_ALIGNED_BBOX_TRANSFORMBIDIRECTIONAL_SEQUENCE_LSTMBIDIRECTIONAL_SEQUENCE_RNNBOX_WITH_NMS_LIMITCASTCHANNEL_SHUFFLEDETECTION_POSTPROCESSINGEQUALEXPEXPAND_DIMSGATHERGENERATE_PROPOSALSGREATERGREATER_EQUALGROUPED_CONV_2DHEATMAP_MAX_KEYPOINTINSTANCE_NORMALIZATIONLESS
LESS_EQUALLOGLOGICAL_ANDLOGICAL_NOT
LOGICAL_ORLOG_SOFTMAXMAXIMUMMINIMUMNEG	NOT_EQUALPAD_V2POWPRELUQUANTIZEQUANTIZED_16BIT_LSTMRANDOM_MULTINOMIAL
REDUCE_ALL
REDUCE_ANY
REDUCE_MAX
REDUCE_MINREDUCE_PROD
REDUCE_SUM	ROI_ALIGNROI_POOLINGRSQRTSELECTSINSLICESPLITSQRTTILETOPK_V2TRANSPOSE_CONV_2DUNIDIRECTIONAL_SEQUENCE_LSTMUNIDIRECTIONAL_SEQUENCE_RNNRESIZE_NEAREST_NEIGHBORr"   r"   r"   r#   r$   %   s    r$   c                   @      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_RELUFUSED_RELU1FUSED_RELU6r"   r"   r"   r#   r      
    r   c                   @   s   e Zd ZdZdZdZdS )OperandValueSourceTyper   r   r   N)r   r   r   	IMMEDIATENUMBERED_BUFFER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rhs	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dims
ITEM_SIZESsizedr"   r"   r#   tensor_size   s   
r   c                 C   s   t | }|||< t|S r   )listtuple)tupindexvalue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                   @   r   )DimOrderr   r   r   i  N)r   r   r   PRESUMED_CONTIGUOUSCHANNELS_LASTSCALAR_OR_VECTORUNKNOWN_CONSTANTr"   r"   r"   r#   r     r   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#Representation 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)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rtdt |  t |dkrtdt | t| }t|}t |t |kr2tdt |t |kr>tdg }t||D ]+\}}|dkrS|| qE|dkr]|| qE||krg|| qEtd|  d| t|S )Nr   z!shape1 must have length > 0, got z!shape2 must have length > 0, got z.Non-equal-rank broadcast is not supported yet.r   zCannot broadcast shapes: z and )lenAssertionErrorr   r  zipappendr   )shape1shape2s1s2retd1d2r"   r"   r#   broadcast_shapes   s4   r!  c                 C   s   | \}}}}|j dks|jdkrtd|r7|d |j |j |j |j }|d |j |j |j	 |j	 }	n ||j |j |j |j d }||j |j	 |j
 |j d }	|dkr]d}|dkrcd}	||||	f}
|
S )Nr   zDilation not supported yet.r   )r  r  r  r   r   r   r   r   r   r   r   )image_shapeargs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u r| S |t ju r t| d gt| dd   | d g S |t ju r<t| dks:t| dks:tdt|  | S |t ju rC| S t	d|d)Nr   r   r   z4SCALAR_OR_VECTOR requires len(shape) == 0 or 1, got zBad dim_order: .)
r  r  r	  r   r   r
  r  r  r  r  r  r  r"   r"   r#   	fix_shape&  s   

(

r0  c                 C   s8   | t jt jfv r
|S | t ju rg d| S td|  )Nr   r   r   r   z%expected DimOrder.CHANNELS_LAST, got )r  r  r
  r	  r  )r  r   r"   r"   r#   reverse_map_dim:  s
   
r2  c                 C   s   d|  d| S )Ns__r"   )op_iddimr"   r"   r#   	flex_nameF  s   r7  c                   @   s  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'i dEdFdG dHdIdG dJdKdG dLdMdG dNdOdG dPdQdG dRdSdG dTdUdG dVdWdG dXdYdG dZd[dG d\d]dG d^d_dG d`dadG dbdcdG dddedG dfdgdG i dhdidG djdkdG dldmdG dndodG dpdqdG drdsdG dtdudG dvdwdG dxdydG dzd{dG d|d}dG d~ddG dddG dddG dddG dddG dddG ddG ddG ddG ddG ddG ddG dZ(dd Z)dd Z*dd Z+dd Z,dd Z-dd Z.dd Z/dd Z0dd 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   st   g | _ g | _g | _g | _g | _g | _g | _g | _i | _i | _	i | _
i | _i | _g | _d| _|| _|d u r8i }d S 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_weightsweight_offsetuse_int16_for_qint16)r  configrI  r"   r"   r#   __init__M  s&   z_NnapiSerializer.__init__c                 C   s
   t | jS r   )r  r:  r  r"   r"   r#   get_next_operand_idc     
z$_NnapiSerializer.get_next_operand_idc                 C   sV   t |tstdt| || jv rtd||  }| j| || j|< |S )Nexpected Operand, got zDuplicate tensor: )	
isinstancer  r  typerE  r  rL  r:  r  )r  jitvaloper
operand_idr"   r"   r#   add_tensor_operandi  s   


z#_NnapiSerializer.add_tensor_operandc                 C   s4   t |tstdt| |  }| j| |S )NrN  )rO  r  r  rP  rL  r:  r  )r  rR  rS  r"   r"   r#   add_anonymous_tensor_operandw  s
   
z-_NnapiSerializer.add_anonymous_tensor_operandc           	      C   s  t |jdd}d}d}|dkrtj}nh|dkrtj}n`|dkr-tj}| }| }nP|dkrHtj}| }| }|dkrGt	d	| n5|d
krt| j
rpt|dd }tjtjf}||v rh|}|j}|j}ntd| dtdtd|j dtt|j||||dS )Nztorch.         r   float32int32quint8qint32z!qint32 zero_point must be 0, got 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  rI  getattrr   r!   nnapi_scalennapi_zero_pointr  r  r   r  )	r  tensorr  ra  r  r  r   r]  op_codesr"   r"   r#   torch_tensor_to_operand~  sX   

z(_NnapiSerializer.torch_tensor_to_operandc           	   
   C   sx   t |ddr	tjntj}| ||}| ||}| j| t|j	D ]\}}|dkr9| 
||d| d| d q#|S )N
nnapi_nhwcFr   zargs[z].shape[])re  r  r	  r  rj  rT  r?  r  	enumerater  compute_operand_shape)	r  arg_idxrQ  rh  r  toperrS  r6  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rA|dddd}| j
| |S )Nr   iiir   r   r   )rj  r  r:  r  r   r   r  r;  r   r   rG  r=  structpackr  r	  permute)r  rh  r  rp  rS  tsizebuf_numoffsetr"   r"   r#   add_tensor_operand_for_weight  s   


z._NnapiSerializer.add_tensor_operand_for_weightc                 C   s   t |tstdt| ||f}|| jvr=t| j}| jt||t	j
dd | j|tjf | j| || j|< | j| S )Nzdims must be a tuple, got rW  r   )rO  r   r  rP  rF  r  r:  r  r  r  r
  r;  r   r   r=  )r  coder   r   	cache_keyrS  r"   r"   r#   add_immediate_operand  s   




z&_NnapiSerializer.add_immediate_operandc                 C      |  tjtd|dS )Nir"   )r|  r   r   rs  rt  r  r   r"   r"   r#   add_immediate_int_scalar     z)_NnapiSerializer.add_immediate_int_scalarc                 C   r}  )Nfr"   )r|  r   r   rs  rt  r  r"   r"   r#   add_immediate_float_scalar  r  z+_NnapiSerializer.add_immediate_float_scalarc                 C   s   |  tj|r
ddS 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   )rE  )r  rQ  r"   r"   r#   has_operand_for_jitval  rM  z'_NnapiSerializer.has_operand_for_jitvalc                 C   s   | j | }|| j| fS r   )rE  r:  )r  rQ  rS  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  rQ  r5  rR  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 r| |d\}}| ||}|| j| fS N
TensorType)rE  getget_constant_valuery  r:  )r  rQ  r  rS  r4  r   r"   r"   r#   get_tensor_operand_or_constant	  s
   z/_NnapiSerializer.get_tensor_operand_or_constantc                 C   s(   |  |d\}}| |}|| j| fS r  )r  ry  r:  )r  rQ  r4  r   rS  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 rtd|d|| j |< d S )Njitval z already in tensor_sequences)rD  r  )r  rQ  r;  r"   r"   r#   add_tensor_sequence  s   
z$_NnapiSerializer.add_tensor_sequencec                 C   s,   || j v rtd|d||f| j |< d S )Nr  z already in constants)rC  r  r  rQ  ctyper   r"   r"   r#   add_constant_value   s   
z#_NnapiSerializer.add_constant_valueNc                 C   sd   | j |}|d u rtd|d|\}}|d ur0| |kr0t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_  )rC  r  r  kind)r  rQ  typekindrecordr  r4  r"   r"   r#   r  %  s   
z#_NnapiSerializer.get_constant_valuec                 C   sX  |du r|j }nt|t|j kr tdt| dt|j  dg}t|D ]0\}}|dkr7|t| n|dkrD|t|| n|dkrN|d ntd|d	 q'|d
 d|}|j	t
jkrnd| dS |j	t
jkrzd| dS |j	t
jkrd|j d|j d| dS |j	t
jt
jfv r| jrd| dS tdtd|j	 )zHReturn a TorchScript expression to build a template for a given operand.Nzshape length z != oper.shape length (r   0z-Unknown dim value, dimensions should be >= -1,)rV  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  rm  r  r`  r7  r  joinr   r   r   r   r   r  r  r!   r   rI  )r  r5  rR  r  shape_partsr   r  
shape_coder"   r"   r#   operand_to_template_torchscript2  sZ   


z0_NnapiSerializer.operand_to_template_torchscriptc                 C   s   |  ||t|| d S r   )rn  r7  )r  	out_op_idout_dimin_op_idin_dimr"   r"   r#   forward_operand_shapeh  s   z&_NnapiSerializer.forward_operand_shapec                 C   s    | j t|| d|  d S )Nz = )rA  r  r7  )r  r5  r6  exprr"   r"   r#   rn  k  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   r1  r   )
r  r  _replacer  r	  r  rU  r  r$   r   )r  in_idrR  out_operr?  r@  r"   r"   r#   transpose_to_nhwcp  s   

z"_NnapiSerializer.transpose_to_nhwcc                 C   s   |j |j kr||||fS |j |j f}|tjtjfkr$| ||||f S |tjtjfkr6||f| || S td|j d|j )Nz2Automatic transpose not supported for dim_orders: z, )r  r  r  r	  r  r  )r  in0_idin0_operin1_idin1_operordersr"   r"   r#   transpose_for_broadcast  s   z(_NnapiSerializer.transpose_for_broadcastc                 C   sZ   |  |\}}| dkr"|  dkr td|   |S td|d|d)NListTypeIntTypez"expected ListType of IntType, got zCan't handle size arg of type 'z' for 'r_  )r  r  getElementTyper  r  r  r"   r"   r#   get_size_arg  s   z_NnapiSerializer.get_size_argc           	      C   s   dd |D }|d dkrt d|d  |d |d g}|d |d g}|d	 |d
 g}|d |d g}|d }t|dkrIt dt| |ddgkrVt d| | |||||S )Nc                 S   s   g | ]}|  qS r"   )item.0r~  r"   r"   r#   
<listcomp>  s    zD_NnapiSerializer.get_conv_pool_args_2d_from_pack.<locals>.<listcomp>r   r   zexpected pc[0] == 2, got r   r   r	   r
   r   r   r   r   r   zexpected len(pc) == 11, got z'expected output_padding == [0, 0], got )r  r  get_conv_pool_args_2d_common)	r  kernel_sizepacked_configpcstridespaddings	dilations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r%| |d\}	}
nd }
| |||||
S )Nr   r  )r  r  r  )r  r  stridepaddingdilationr  r  r  r  r4  r  r"   r"   r#   get_conv_pool_args_2d_from_jit  s   




z/_NnapiSerializer.get_conv_pool_args_2d_from_jitc           
      C   s   t |}t|dkrtdt| t|dkr"tdt| t|dkr1tdt| t|dkr@tdt| |\}}||||g}	t|| |	 | |g  S )Nr   z expected len(kernels) == 2, got z expected len(strides) == 2, got z!expected len(paddings) == 2, got z"expected len(dilations) == 2, got )r   r  r  r   )
r  r  r  r  r  r  kernelsphpwreal_paddingsr"   r"   r#   r    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|| | | qM|j }| dkrrtd|  | dkrtd|  |d}dg}|  d	kr|g}d
}n|  dkr| j| }t|}n	td|  |d urt|t|krtdt| dt| t|D ]0\}}| j| }
| j
|
 |
| j|
 jj |r|| nd }|
| |
| j|
 |d  q|
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rdtd| t%|d }t| jD ]G\}
\}}}}}t&||}t|D ]"\}}|dkrt'||}| j(
d| dt)|
|  |d7 }qt*dd |D }|
| +| qo|#| |
| +| j, |
| +| j |
| +| j | j(#| t--dd$|| j.||| j(|fS )NFTr   zProcessing node #%d: %rz%expected retn.inputsSize() == 1, got r   z&expected retn.outputsSize() == 0, got zreturn [r  r  	TupleTypezUnsupported return type: zreturn_shapes length z != return_values length r  rl  iiiiiic                 s   s0    | ]\}}}}}t d |t|||V  qdS )iifiN)rs  rt  r  )r  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 )rr  N)rs  rt  )r  xr"   r"   r#   r  +  s         r	   z)model_offset must be divisible by 4, got z
ser_model[z] = c                 s        | ]}|d kr
|ndV  qdS )r  r   Nr"   r  r   r"   r"   r#   r  D      r~  )/r  nextgraphr?  r  rP  rm  r  r   rq  r  r:  r  r   nodesr   debugadd_nodereturn_node
inputsSizer  outputsSizeinputsAtr  rD  r  r  rE  r@  r  rs  rt  r;  r<  serialize_valuesr  r  r  r0  r2  rA  r7  r   serialize_intsr>  r  rG  ) r  modelr?  return_shapesinp_dim_ordersout_dim_ordersself_jitvalro  input_valueinput_tensorr5  idxnoderetn
retn_inputtemplate_return_linesreturn_valuesretval_countr~  vr  versionheaderserialized_valuesserialized_value_datamodel_offsetr4  r   r  r   r  pt_dr"   r"   r#   serialize_model  s   








	





z _NnapiSerializer.serialize_modelc           	   	   C   s   g }g }t | jt | jkrtdt | j dt | j t| j| jD ]*\\}}}t |}|d dB d }|d||   }|td||| || q%||fS )Nzvalues length z != value_data length r   r   r  rr  )r  r;  r=  r  r  r  rs  rt  )	r  r  r  op_indexsource_typedatasource_lengthphysical_lengthpadded_datar"   r"   r#   r  W  s   z!_NnapiSerializer.serialize_valuesc                 C   s   t  d|  S r  )r  r  )intsr"   r"   r#   r  l  s   z_NnapiSerializer.serialize_intszprim::GetAttrc                 C   
   |  |S r   )add_getattrr  r  r"   r"   r#   <lambda>q     
 z_NnapiSerializer.<lambda>zprim::Constantc                 C   r  r   )add_constant_noder
  r"   r"   r#   r  r  r  zprim::ListConstructc                 C   r  r   )add_list_constructr
  r"   r"   r#   r  s  r  zprim::TupleConstructc                 C   r  r   )add_tuple_constructr
  r"   r"   r#   r  t  r  zaten::unsqueezec                 C   r  r   )add_unsqueezer
  r"   r"   r#   r  u  r  zaten::toc                 C   r  r   )add_tor
  r"   r"   r#   r  v  r  zaten::detachc                 C   r  r   	_identityr
  r"   r"   r#   r  w  r  zaten::reshapec                 C   r  r   )add_reshaper
  r"   r"   r#   r  x  r  zaten::flattenc                 C   r  r   )add_flattenr
  r"   r"   r#   r  y  r  zaten::slicec                 C   r  r   )	add_slicer
  r"   r"   r#   r  z  r  z
aten::sizec                 C   r  r   )add_sizer
  r"   r"   r#   r  {  r  z	aten::catc                 C   r  r   )add_catr
  r"   r"   r#   r  |  r  z
aten::meanc                 C   r  r   )add_meanr
  r"   r"   r#   r  }  r  zaten::quantize_per_tensorc                 C   r  r   )add_quantizer
  r"   r"   r#   r  ~  r  zaten::dequantizec                 C   r  r   )add_dequantizer
  r"   r"   r#   r    r  z	aten::addc                 C      |  |tjtjS r   )add_add_sub_opr$   rw   r   r   r
  r"   r"   r#   r        
z	aten::subc                 C   r  r   )r  r$   r   r   r   r
  r"   r"   r#   r    r  z	aten::mulc                 C   r  r   )(add_pointwise_simple_binary_broadcast_opr$   r   r   r   r
  r"   r"   r#   r    r  z	aten::divc                 C   r  r   )r  r$   r   r   r   r
  r"   r"   r#   r    r  z
aten::reluc                 C      |  |tjS r   )add_pointwise_simple_unary_opr$   r   r
  r"   r"   r#   r        zaten::sigmoidc                 C   r   r   )r!  r$   r   r
  r"   r"   r#   r    r"  zaten::softmaxc                 C   r  r   )add_softmaxr
  r"   r"   r#   r    r  zaten::hardtanhc                 C   r  r   )add_hardtanhr
  r"   r"   r#   r    r  zaten::avg_pool2dc                 C   r  r   )add_avg_pool2dr
  r"   r"   r#   r    r  zaten::max_pool2dc                 C   r   r   )add_pool2d_noder$   r   r
  r"   r"   r#   r    r"  zaten::adaptive_avg_pool2dc                 C   r  r   )add_adaptive_avg_pool2dr
  r"   r"   r#   r        zaten::upsample_nearest2dc                 C   r  r   )add_upsample_nearest2dr
  r"   r"   r#   r    r(  zaten::preluc                 C   r  r   )add_prelu_opr
  r"   r"   r#   r    r  zaten::addmmc                 C   r  r   )	add_addmmr
  r"   r"   r#   r    r  zaten::linearc                 C   r  r   )
add_linearr
  r"   r"   r#   r    r  zaten::_convolutionc                 C   r  r   )add_conv_underscorer
  r"   r"   r#   r    r  zaten::conv2dc                 C   r  r   )
add_conv2dr
  r"   r"   r#   r    r  zaten::log_softmaxc                 C   r  r   )add_log_softmaxr
  r"   r"   r#   r    r  zquantized::linearc                 C   r  r   )add_qlinearr
  r"   r"   r#   r    r  c                 C   r   r   add_qconv2dr   r   r
  r"   r"   r#   r    r"  c                 C   r   r   )r2  r   r   r
  r"   r"   r#   r    r"  c                 C   s   | j |tjddS )NT)r%  r1  r
  r"   r"   r#   r    s    c                 C   r  r   )add_qaddr$   rw   r   r   r
  r"   r"   r#   r    r  c                 C   r  r   )r3  r$   rw   r   r   r
  r"   r"   r#   r    r  c                 C   r  r   )r3  r$   r   r   r   r
  r"   r"   r#   r    r  )z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  r  adderr"   r"   r#   r    s   z_NnapiSerializer.add_nodec                 C   s,   |  |d\}}|d}|| j|< d S r9  )r  r  	outputsAtrE  )r  r  r  _in_operrQ  r"   r"   r#   r    s   
z_NnapiSerializer._identityc                 C   s   |  dkrtd|   | dkrtd|  | |d\}}t|ds6td| |d}t||}|	d}|
 }| ||| d S )Nr   %expected node.inputsSize() == 1, got &expected node.outputsSize() == 1, got r   z
__torch__.z3expected obj_ctype to start with '__torch__.', got name)r  r  r  r  r  r`  
startswithr  re  r6  rP  r  )r  r  	obj_ctypeobjr:  r   outputr  r"   r"   r#   r	    s$   


z_NnapiSerializer.add_getattrc                 C   sh   |  dkrtd|   | dkrtd|  |d}| }| }| ||| d S )Nr   z%expected node.inputsSize() == 0, got r   r9  )r  r  r  r6  rP  toIValuer  )r  r  r>  r  r   r"   r"   r#   r    s   
z"_NnapiSerializer.add_constant_nodec           	      C   s   |  dkrtd|   |d}| }g }g }| D ].}|d ur8|| jv r8| |\}}|| nd }|d urL|  dkrL|| q d }q |d urZ| 	||| |d urd| 
|| |d u rs|d u rutd|d S d S )Nr   r9  r   r  zMUnable to handle ListConstruct node.  Neither all constants nor all tensors. )r  r  r6  rP  r?  rC  r  r  r  r  r  r  )	r  r  r>  r  
const_valstensorsinpr4  valr"   r"   r#   r    s2   
z#_NnapiSerializer.add_list_constructc                 C   sD   |  dkrtd|   |d}t| }| || d S )Nr   r9  r   )r  r  r6  r   r?  r  )r  r  r>  r;  r"   r"   r#   r    s   
z$_NnapiSerializer.add_tuple_constructc                 C   s  |  dkrtd|   | dkrtd|  | |d\}}| |dd\}}|jtjkrAtd|j |dkrG|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   %expected node.inputsSize() == 2, got r   r9  r   r  z,expected dim_order PRESUMED_CONTIGUOUS, got r  )r  r  r  r  r  r  r  r  r  r  r  r   insertr   r  r  rT  r6  r  r$   r   )r  r  r  in_operr4  r6  real_dimout_shape_listr,  r  r?  r@  r"   r"   r#   r    s2   



z_NnapiSerializer.add_unsqueezec                 C   s   |  | d S r   r  r
  r"   r"   r#   r  1  s   z_NnapiSerializer.add_toc                 C   sV  |  dkrtd|   | dkrtd|  | |d\}}| |d\}}| dkrAtd|  |  dkrTtd	|   t|dko_|d d
k}|j	t
jkrl|sltdtd|j|j}|j|t
jd}d gd }	||	d< | ||	d< d gd }
| |d||
d< | tj|	|
 d S )Nr   rD  r   r9  r   r  z#expected shape_ctype ListType, got r  z)expected shape element type IntType, got r  zSCurrently, reshape is only supported on NHWC tensors if the target size is [X, -1].r/  )r  r  r  r  r  r  r  r  r  r  r  r  r  torchzerosexpandr  reshaper  r  rT  r6  r  r$   r   )r  r  r  rG  shape_ctyper  is_trivial_reshaper,  r  r?  r@  r"   r"   r#   r  5  sB   

z_NnapiSerializer.add_reshapec              	   C   s@  |  dkrtd|   | dkrtd|  | |d\}}| |dd\}}| |dd\}}t|jdkoY|jd dkpY|jd dkoY|jd dk}|jt	j
krf|sftd	|dk rq|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 rtd|jd | |j|d d   }
|
ddkrt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   %expected node.inputsSize() == 3, got r   r9  r   r  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"   r  r6  r"   r"   r#   r    s    z/_NnapiSerializer.add_flatten.<locals>.<genexpr>z-Flattening flexible dims is not supported yetzOnly 1 dim can be flexibler/  c                 s   r  )r   r  Nr"   rQ  r"   r"   r#   r    r  )r  r  r  r  r  r  r  r  r  r  r  r  	functoolsreduceoperatormulanycountr  rT  r6  rm  r  r   r   r  r  r$   r   )r  r  r  rG  _start_ctype	start_dim
_end_ctypeend_dimis_trivial_flattenr,  non_flattened_dimsr  out_idr  r6  inputs_1r?  r@  r"   r"   r#   r  `  sd   (  

z_NnapiSerializer.add_flattenc                    s  |  dkrtd|   | dkrtd|  | |d\}}| |d\} | |d\}| |d\}| |d\}d u rVdd u r]tjdk ri|j  7 ntjkrpd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rt
d
  t fddt|jD }| |d|j|d}d}t|D ]\}}	|	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
   %expected node.inputsSize() == 5, got r   r9  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"   r  r~  r6  )	dim_valueout_lenr"   r#   r    s    
z-_NnapiSerializer.add_slice.<locals>.<genexpr>rE  r   c                       g | ]
}| kr
nd qS )r   r"   r  )rb  start_valuer"   r#   r        z._NnapiSerializer.add_slice.<locals>.<listcomp>c                    s    g | ]\}}| krn|qS r"   r"   ra  )rb  
stop_valuer"   r#   r    s    c                    rd  )r   r"   r  )rb  
step_valuer"   r#   r    rf  r   )r  r  r  r  r  r  sysmaxsizer  r  r  r   rm  rT  r6  r  r  r  ranger  r  r  r$   r   )r  r  r  rG  r4  r,  r^  end_maskr  r6  r?  r@  r"   )rb  rc  re  rh  rg  r#   r    s   





z_NnapiSerializer.add_slicec                 C   s   |  dkrtd|   | dkrtd|  | |d\}}| j|d \}}|j| }|d}| ||	 | d S )Nr   rD  r   r9  r   )
r  r  r  r  r  rC  r  r6  r  rP  )r  r  r4  rG  r   resr>  r"   r"   r#   r    s   

z_NnapiSerializer.add_sizec              	      s|  |  dkrtd|   | dkrtd|  | j|d }| |dd\} t|dkr@tdt| g }d }d}|D ]l}| |\}}	|d u rbt|	j	 d}
|	j
|
d	}|	j|jkrttd
|	j d|j |	j|jkrtd|	j d|j t|	j	 dt|j	 dkrtdt|	j	 d dt|j	 d || ||	j	  7 }qH|d u rtd|j
t|j	 |d	}|	jtjkrt|j	dkrtdt|j	 g d  }n }| |d|}t|j	D ],\}}|dkr"| krd fdd|D }| ||| q| |||d | q|| |g }d gd }||d< | tj|| d S )Nr   rD  r   r9  r   r  zexpected len(tensors) > 0, got r  rE  zin_oper.op_type z != out_oper.op_type zin_oper.dim_order z != out_oper.dim_order zshape mismatch: z != zout_oper must not be Noner	   z9expected len(out_oper.shape) == 4 for CHANNELS_LAST, got r   r   r   r    + c                 3   s    | ]}t | V  qd S r   )r7  )r  ip_idr6  r"   r#   r  <      z+_NnapiSerializer.add_cat.<locals>.<genexpr>)r  r  r  rD  r  r  r  r  r   r  r  r   r  r  r  r	  rT  r6  rm  r  rn  r  r  r  r$   ry   )r  r  rA  r4  in_idsr  out_dim_sizerB  r  rG  r,  	nnapi_dimr^  r  r   r  r?  r@  r"   rq  r#   r    sx   "



z_NnapiSerializer.add_catc                 C   s&  |  dkrtd|   | dkrtd|  | |d\}}| |d\}}| dkrAtd|  |  dkrTtd	|   | |d
d\}}| |dd |jt	j
krt|jdkrtdt|j dd |D }n|}t }	|D ]}
|
dk r|
t|j7 }
|	|
 q|jt	j
kr|s|	d
dhstd|	 t	j}n|j}g }t|jD ]\}}||	vr|| q|r|d q|j||d}d gd }||d< | ||d< | ||d
< d gd }| |d||d< | tj|| d S )Nr	   %expected node.inputsSize() == 4, got r   r9  r   r  z!expected dim_ctype ListType, got r  z'expected dim element type IntType, got r   BoolTyper   NoneTypez8expected len(in_oper.shape) == 4 for CHANNELS_LAST, got c                 S   s   g | ]}g d | qS )rn  r"   r  r"   r"   r#   r  c  s    z-_NnapiSerializer.add_mean.<locals>.<listcomp>z/expected collapsed_dims to include {2, 3}, got r/  )r  r  r  r  r  r  r  r  r  r  r	  r  r  setadd
issupersetr  rm  r  r  r  r  rT  r6  r  r$   r   )r  r  r  rG  	dim_ctyper6  r4  keep_dimru  collapsed_dimsr   out_dim_orderr,  r~  r  r  r?  r@  r"   r"   r#   r  H  sh   


z_NnapiSerializer.add_meanc                 C   s  |  dkrtd|   | dkrtd|  | |d\}}|jtjkr2td| 	|dd\}}| 	|dd	\}}| 	|d
d	\}}|t
jjkr]tdtj}|j|||d}	d gd }
||
d< d gd }| |d|	|d< | tj|
| d S )Nr	   rv  r   r9  r   zqMost hardware backends prefer NHWC quantized tensors.  Try setting `t.nnapi_nhwc = True` on your tensor inputs.  	FloatTyper   r  r   zKPyTorch NNAPI export only supports quantized tensors with the quint8 dtype.r   r  r  )r  r  r  r  r  r  r  r	  r  r  r   r   r   r   r   r  rT  r6  r  r$   r   )r  r  r  rG  r4  r  r  scalar_typer   r  r?  r@  r"   r"   r#   r    s>   

z_NnapiSerializer.add_quantizec                 C   s   |  dkrtd|   | dkrtd|  | |d\}}|jtjddd}d gd }||d< d gd }| |	d||d< | 
tj|| d S )Nr   r8  r9  r   rW  r  )r  r  r  r  r  r  r   r   rT  r6  r  r$   r}   )r  r  r  rG  r  r?  r@  r"   r"   r#   r    s&   

z_NnapiSerializer.add_dequantizec                 C   s   |  dkrtd|   | dkrtd|  | |d\}}|}|tjkr<|jtj	kr<|j
ddd}| |d|}t|jD ]\}}|dkrZ| |||| qJd gd }	||	d< d gd }
||
d< | ||	|
 d S )Nr   r8  r9  r   g      p?)r  r  )r  r  r  r  r  r$   r   r   r   r   r  rT  r6  rm  r  r  r  )r  r  r  r  rG  r  r^  r  r6  r?  r@  r"   r"   r#   r!    s.   


z._NnapiSerializer.add_pointwise_simple_unary_opqparamsc             	   C   s  |  dkrtd|   |d  dkr(td|d   |d  dkrAtd|d   | |dr`| |d\}}| |d|j\}}n'| |dr| |d\}}| |d|j\}}nt	d| d|j
|j
krtd	|j
 d
|j
 | ||||\}}}}t|j|j}	|j|	d}
|dur|\}}|
j||d}
| |d|
}tt|j|jD ]L\}\}}|dkr|dkr| |||| q|dkr|dkr| |||| q|dkr|dkr| jdt|| dt||  | |||| qdgd }||d< ||d< | ||d< dgd }||d< | ||| dS )zFHelper for pointwise binary broadcast ops with superfluous extra args.r   r9  r   r  %expected inputsAt(0) TensorType, got %expected inputsAt(1) TensorType, got zCan't do a NNAPI binary op: z on two constantszin0_oper.op_type z != in1_oper.op_type rE  Nr  r  zassert z == r   r   )r  r  r  rP  r  r  r  r  r  r  r   r  r!  r  r  rT  r6  rm  r  r  rA  r  r7  r  r  )r  r  r  	fuse_coder  r  r  r  r  r,  r  r  zpr^  r  d0r  r?  r@  r"   r"   r#   _do_add_binary  sp   




z_NnapiSerializer._do_add_binaryc                 C   s0   |  dkrtd|   | ||| d S )Nr   rD  )r  r  r  )r  r  r  r  r"   r"   r#   r  /  s
   z9_NnapiSerializer.add_pointwise_simple_binary_broadcast_opc                 C   sV   |  dkrtd|   | |dd\}}|dkr"td| ||| d S )Nr   rP  r   r  r   z*NNAPI does not support add/sub with alpha.)r  r  r  r  r  r  )r  r  r  r  r4  alphar"   r"   r#   r  6  s   z_NnapiSerializer.add_add_sub_opc                 C   sd   |  dkrtd|   | |dd\}}| |dd\}}| j|||||fd d S )Nr	   rv  r   r  r   r  r  )r  r  r  r  r  )r  r  r  r  r4  r  r  r"   r"   r#   r3  D  s   z_NnapiSerializer.add_qaddc                 C   s   |  dkrtd|   | |d\}}| |dd\}}| |d|}t|jD ]\}}|dkrB| 	|||| q2d gd }	||	d< | 
d|	d< | ||	d< d gd }
||
d< | tj|	|
 d S )Nr   rP  r   r   r  g      ?r   )r  r  r  r  r  rT  r6  rm  r  r  r  r  r  r$   r   )r  r  r  rG  r4  softmax_dimr^  r6  r   r?  r@  r"   r"   r#   r#  O  s(   

z_NnapiSerializer.add_softmaxc                 C   s   |  dkrtd|   | dkrtd|  | |d\}}| |dd\}}| |dd\}}tjtjd}|	||f}|d u rTt
d	d gd }	||	d< d gd }
| |d||
d< | ||	|
 d S )
Nr   rP  r   r9  r   r  r   ))r  r   )r   r   z9NNAPI only supports hardtanh with args (-1, 1) or (0, 6).)r  r  r  r  r  r  r$   r   r   r  r  rT  r6  r  )r  r  r  rG  r4  min_valmax_valop_mapr  r?  r@  r"   r"   r#   r$  i  s0   

z_NnapiSerializer.add_hardtanhc                 C   s  |  dkrtd|   | dkrtd|  |d  dkr7td|d   |d  dkrPtd|d   | |d\}}| |d\}}t|j	dkrutd	t|j	 |j	d dkrtd
|j	d  |j	d dkr|
 rtd| |d|}t|j	D ]\}}|dkrq|dkrtd| |||| qd gd }	||	d< ||	d< d gd }
||
d< | tj|	|
 d S )Nr   rD  r   r9  r   r  r  r  z%expected len(w_oper.shape) == 1, got z"expected w_oper.shape[0] > 0, got z8Per-channel PReLU only supports channels_last right now.z.PReLU requires fixed size for dim 0 and dim 1.)r  r  r  r  rP  r  r  r  r  r  r  r  rT  r6  rm  r  r  r$   r   )r  r  r  rG  w_idw_operr^  r6  r   r?  r@  r"   r"   r#   r*    sX   

z_NnapiSerializer.add_prelu_opc                 C   s  |  dkrtd|   | dkrtd|  | \}}}}}}|p+|}| | ||||}	|	jdksA|	jdkrEtd| 	|\}
}t
|jdkr]tdt
|j 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   z%expected node.inputsSize() == 6, got r   r9  z'NNAPI does not support dilated pooling.r	   )expected len(image_oper.shape) == 4, got Fr   r   r   r   r
   r   r   r   r   rE  )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  rT  r6  r  r  )r  r  r  imagekernelr  r  r  
_ceil_moder#  image_id
image_operr,  r  r?  r@  r"   r"   r#   r&    sR   

z _NnapiSerializer.add_pool2d_nodec                 C   s  |  dkrtd|   | dkrtd|  | \}}}}}}}| |\}	}
| |\}	}|
r;|r?td| | |||}| |\}}t	|j
dkratdt	|j
 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   %expected node.inputsSize() == 7, got r   r9  zANNAPI doesn't support count_include_pad=False or divisor_overrider	   r  Fr   r   r   r   r
   r   r   r   r   rE  ) 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  rT  r6  r   _handle_conv_pool_flexible_inputr  r$   rx   )r  r  r  r  r  r  r  count_include_paddivisor_overrider4  count_include_pad_valuedivisor_override_valuer#  r  r  r,  r  r?  r@  r^  r"   r"   r#   r%    sl   

z_NnapiSerializer.add_avg_pool2dc           
      C   s  |  dkrtd|   | dkrtd|  | |d\}}t|jdkr9tdt|j | |d\}}| dkrRtd	|  |	  d
kretd|	   |ddgkrot
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   rD  r   r9  r   r	   r  r  "expected size_ctype ListType, got r  (expected size element type IntType, got z@NNAPI only supports adaptive_avg_pool2d with output size (1, 1).r   r   r
   r   r   r   r   r   rE  )r  r  r  r  r  r  r  r  r  r  r  r   r  r  r   r   r  rT  r6  r  r  r$   rx   )
r  r  r  r  
size_ctypesize_argr,  r  r?  r@  r"   r"   r#   r'  3  s^   

z(_NnapiSerializer.add_adaptive_avg_pool2dc                 C   s  |  dks|  dkstd|   | dkr$td|  |  dkr2| \}}}n| \}}}}| |\}}|  dkrO| |\}	}
n0| |\}}| |\}}| dkrltd|  | dkr{td|  |}	|}
| |\}}t|jdkrtd	t|j | dkr|	 dkrt	d
| dkr:| dkrtd|  |
  dkrtd|
   |	 dkrtd|	  |
d urtd|
 t|tstdt| |stdtdd |D stdt|dkr|d }t|dkr'tdt| |d }|d }| |}| |}n|	 dkr|	 dkrQtd|	  |	
  dkretd|	
   | dkrutd|  |d urtd| t|
tstdt|
 |
stdtd d |
D std!t|
dkr|
d }
t|
dkrtd"t|
 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s|jd dkrt	d%d&D ]A}|j| dkr\| dkr:| ||||d   q|	 dkrX| ||d'|
|d   d(t|| d) qt	d#qd gd }||d< ||d< ||d< | ||d< d gd }||d< | tj|| d S )*Nr   r	   z*expected node.inputsSize() == 3 or 4, got r   r9  rx  z%expected scale_h_ctype NoneType, got z%expected scale_w_ctype NoneType, got r  z'Size and scale cannot both be non-None.r  r  r  r  z#expected scale_ctype NoneType, got zexpected scale_arg None, got z"expected size_arg to be list, got z!expected size_arg to be non-emptyc                 s       | ]}t |tV  qd S r   )rO  r  r  rC  r"   r"   r#   r    rr  z:_NnapiSerializer.add_upsample_nearest2d.<locals>.<genexpr>z&expected all size_arg values to be intr   z!expected len(size_arg) == 2, got r   z#expected scale_ctype ListType, got r  z+expected scale element type FloatType, got z"expected size_ctype NoneType, got zexpected size_arg None, got z#expected scale_arg to be list, got z"expected scale_arg to be non-emptyc                 s   r  r   )rO  r  r  r"   r"   r#   r    rr  z)expected all scale_arg values to be floatz"expected len(scale_arg) == 2, got z#Size and scale cannot both be None.rE  z(Flexible batch or channels not supported)r   r   zint(z * r  )r  r  r  r?  r  r  r  r  r  r  r  rO  r   rP  allr  r  r  r  rT  r6  r  rn  r7  r  r  r$   r   )r  r  r  size_jit	scale_jitscale_h_jitscale_w_jitr  r  scale_ctype	scale_argscale_h_ctypescale_h_argscale_w_ctype_scale_w_argr  r  r*  r+  arg_harg_wr,  r  r^  r6  r?  r@  r"   r"   r#   r)  j  s  


 

z'_NnapiSerializer.add_upsample_nearest2dc           
      C   s   |  dkrtd|   | dkrtd|  | \}}}}}||fD ] }| |\}}	| dvrCtd|  |	dkrKtdq+| |d||| d S )	Nr
   r`  r   r9  )r  r  z/expected scale_ctype IntType or FloatType, got z6NNAPI Fully-Connected does not support alpha and beta.T)r  r  r  r?  r  r  r  add_addmm_or_linear)
r  r  jit_bias	jit_input
jit_weightjit_beta	jit_alpharQ  r  scale_valuer"   r"   r#   r+    s*   z_NnapiSerializer.add_addmmc                 C   s`   |  dkrtd|   | dkrtd|  | \}}}| |d||| d S )Nr   rP  r   r9  F)r  r  r  r?  r  )r  r  r  r  r  r"   r"   r#   r,    s   z_NnapiSerializer.add_linearc                 C   sd  |  |\}}| |\}}	t|jdkrtdt|j t|	jdkr0tdt|	j | |d\}
}t|jdkrItdt|j |rR|  }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   )expected len(input_oper.shape) == 2, got r   (expected len(bias_oper.shape) == 1, got r  z,expected len(weight_tensor.shape) == 2, got r   rE  r	   r   )r  r  r  r  r  r  r  
contiguousry  r:  rT  r6  r  r  r  r   r   r  r$   r   )r  r  transpose_weightr  r  r  input_id
input_operbias_id	bias_operr4  weight_tensornnapi_weight_tensor	weight_idweight_operr,  r^  r?  r@  r"   r"   r#   r  &  sD   



z$_NnapiSerializer.add_addmm_or_linearc                 C   s  |  dkrtd|   | dkrtd|  | \}}}}| |\}}t|jdkr>tdt|j | |d\}}	| |d\}}
| |\}}| d	krdtd
|  |	 d \}}|d u rttdt|jdkrtdt|j t|jdkrtdt|j |jd |jd krtd|jd  d|jd  |jd |jd krtd|jd  d|jd  |
 tjkrtd|
  |jtjkr|}n&|jtjkrtd|j tj|  d tj| | d d}| }|j| }t||dtj}| |}|j| |	 }|dkr3td| |dkr<t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	   rv  r   r9  r   r  r  r  LinearPackedParamsBasez2expected weight_ctype LinearPackedParamsBase, got r   raw_bias must not be Nonez)expected len(raw_weight.shape) == 2, got z'expected len(raw_bias.shape) == 1, got zraw_bias.shape[0] z != raw_weight.shape[0] zraw_weight.shape[1] z != input_oper.shape[1] 5expected raw_weight.qscheme() per_tensor_affine, got %expected raw_weight.dtype qint8, got    r  expected multiplier > 0, got 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   )'r  r  r  r?  r  r  r  r  r:  __getstate__qschemerJ  per_tensor_affinera  rZ  qint8!_make_per_tensor_quantized_tensorint_reprr  touint8rc  rd  r  quantize_per_tensorr[  ry  r  r  r:  r  r  r   r   rT  r6  r  r$   r   )r  r  r  jit_packed_weight	jit_scalejit_zero_pointr  r  r4  	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,  r  r?  r@  r"   r"   r#   r0  U  s   









z_NnapiSerializer.add_qlinearc           
      C   sd   |  |\}}| dkr-|rdnd}tj| | |jd}| |}| j| }	||	fS | |S )Nrx  r   r   )ra  )	r  r  rJ  rK  r   ra  ry  r:  r  )
r  r  r  r%  r  _valuebias_idxnnapi_bias_tensorr  r  r"   r"   r#   get_optional_bias  s   


z"_NnapiSerializer.get_optional_biasc                 C   s   |  dkrtd|   | dkrtd|  | \}}}}}}}| |d\}	}
| ||
\}}| |
jdd ||||}| |	dd	d||
||d
t
j	S )Nr   r  r   r9  r  r   r	   r   rW  Fr  r  r  r?  r  r  r  r  add_conv2d_commonr6  r   r   )r  r  	jit_imager  r  
jit_stridejit_padjit_dilation
jit_groupsr4  r  r  
_bias_operr#  r"   r"   r#   r.    sB   z_NnapiSerializer.add_conv2dc                 C   s   |  dkrtd|   | dkrtd|  | \}}}}}}}}	}
}	}	}	}	| |d\}	}| |\}	}| |||\}}| |jdd ||||
}| |	dd	d|||||t
j	S )
Nr%   z&expected node.inputsSize() == 13, got r   r9  r  r   r	   r   rW  r  )r  r  r  r  r  r  r  r  jit_transposer4  r  r  r%  r  r  r#  r"   r"   r#   r-    sP   z$_NnapiSerializer.add_conv_underscorec                 C   s   |  dkrtd|   | dkrtd|  | \}}}| |\}}| |d\}}|j}	d gd }
||
d< | d|
d< | ||
d< d gd }| 	|
d|j|	d|d< | tj|
| d S )	Nr   rP  r   r9  r  r   r   rE  )r  r  r  r?  r  r  r  r  r  rT  r6  r  r  r$   r   )r  r  r  jit_dim_jit_half_to_floatr  r  r4  r6  r,  r?  r@  r"   r"   r#   r/  	  s*   

z _NnapiSerializer.add_log_softmaxc                 C   s  |  dkrtd|   | dkrtd|  | \}}}}| |d\}}	| |d\}}
| |\}}| dkrLtd|  | d	 \}}}|d
kr`td||\}}|\}|d u rotd| |jdd |}|	 t
jkrtd|	  |jt
jkr|}n&|jt
jkrtd|j t
j|  d t
j| | d d}| }| |\}}|j| }t
||d	t
j}| |}|j| |	 }|d	krtd| |dkrtd| |d	|	|
||||||	S )Nr	   rv  r   r9  r  r  Conv2dPackedParamsBasez2expected weight_ctype Conv2dPackedParamsBase, got r   2zexpected pack_version '2', got r  r   r  r  r  r  r  r  )r  r  r  r?  r  r:  r  r  r  r  rJ  r  ra  rZ  r  r  r  r  r  r  rc  rd  r  r  r  r[  ry  r  r  r6  )r  r  r  r%  r  r  r  r  r4  r  r  r  r  pack_versionrA  opt_tensorsr  r  r  r#  r  r  r  r  r  r  r  r"   r"   r#   r2  :	  s   	




z_NnapiSerializer.add_qconv2dc
           !      C   s  |  |\}
}|jd }|jdkrd}|rd}nd}n|j|kr%d}d}ntd|j|  }| |}| j| }| j| }|jt	j
krb|jt	j
krStd|j |jt	j
kratd|j nQ|jt	jkr|jt	jkrvtd	|j |jt	jkrtd
|j t|j|j |jstd|j|j  d|j |jdkrtd|j ntd|j t|jdkrtdt|j t|jdkrtdt|j t|jdkrtdt|j |r,|j\}}}}|dkrtd| || dkrtd| d| || }|dkrtd| ||kr+td| d| n|j\}}}}||krBtd| d| ||jd krWtd| d|jd  | }|rdd}tj}nd}|rmt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   r1  Tz$Group convolution not supported yet.z)expected weight_oper TENSOR_FLOAT32, got z'expected bias_oper TENSOR_FLOAT32, got z.expected weight_oper TENSOR_QUANT8_ASYMM, got z%expected bias_oper TENSOR_INT32, got z#scale mismatch: image*weight scale z != bias scale r   z(expected bias_oper.zero_point == 0, got z#Unsupported input type for conv2d: r	   r  z*expected len(weight_oper.shape) == 4, got r  z(expected weight_oper.shape[0] == 1, got zout_c z must be divisible by in_c z"channel_multiplier must be 1, got z	 != in_c zkern_d z != bias_oper.shape[0] r   r   r   r   r
   r   r   r   r   r   r  )$r  r  r  r  ru  r  ry  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  rT  r  r  )!r  jit_outr  r  r  r  r  r#  r%  r  r  r  in_c	depthwiseweight_permutationr  r  r  r  one_kern_h_kern_wout_cchannel_multiplierkern_dr  num_argsr  r?  r@  r,  r  r^  r"   r"   r#   r  	  s   

















z"_NnapiSerializer.add_conv2d_commonc                 C   sd  |  |\}}|j\}}}	}
|dkr| |d|d |dkr"td|rj|	dkrE| |ddt|d d|j d|j d|j d|j	 
 |
dkrh| |ddt|d d|j
 d|j d|j d|j 
 d S d S |	dkr| |ddt|d d|j d|j d|j	 d	|j d
 |
dkr| |ddt|d d|j d|j d|j d	|j
 d
 d S d S )Nr   z Input channels can't be flexibler   r  z - 1) * ro  z - r   z) // z + 1)r  r  r  r  rn  r7  r   r   r   r   r   r   r   r   )r  r^  r  r#  r%  r  r  r&  in_chr(  r)  r"   r"   r#   r  !
  sB   ..00z1_NnapiSerializer._handle_conv_pool_flexible_input)Fr   )NN)Pr   r   r   rK  rL  rT  rU  rj  rq  r  r  ry  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rn  r  r  r  r  r  r  r   r  staticmethodr  r4  r  r  r	  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  r  r  r  r3  r#  r$  r*  r&  r%  r'  r)  r+  r,  r  r0  r  r.  r-  r/  r2  r  r  r"   r"   r"   r#   r8  L  s6   
3

	

6

|
	
"#$%(+./012345I	!+>QIA("C!64?7 /
i&-
S r8  F)rJ  r  rI  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
    )r8  r   )moduler?  rJ  r  rI  r"   r"   r#   r   F
  s   
r   )r   ) r  enumrR  loggingrT  rs  ri  typingr   r   rJ  	getLoggerr   r   r$   r   r   Enumr   r   r   r   r   r  r  r!  r-  r0  r2  r7  r8  r   r"   r"   r"   r#   <module>   s^   
b

 #                  