U
    d                     @   sP   d dl mZmZ d dlZd dlmZ G dd dejjZdddZ	dd	d
Z
dS )    )OptionalListN)_NnapiSerializerc                       s   e Zd ZU dZeejjj e	d< e
ej e	d< e
ej e	d< ejjeje
ej e
e e
e d fddZejje
ej dd	d
Ze
ej e
ej dddZ  ZS )NnapiModulezTorch Module that wraps an NNAPI Compilation.

    This module handles preparing the weights, initializing the
    NNAPI TorchBind object, and adjusting the memory formats
    of all inputs and outputs.
    compweightsout_templates)shape_compute_module	ser_modelr   inp_mem_fmtsout_mem_fmtsc                    s8   t    || _|| _|| _|| _|| _g | _d | _d S N)	super__init__r	   r
   r   r   r   r   r   )selfr	   r
   r   r   r   	__class__ A/tmp/pip-unpacked-wheel-ua33x9lu/torch/backends/_nnapi/prepare.pyr      s    
zNnapiModule.__init__)argsc                 C   sX   | j d kst| j| j|| _dd | jD | _tjj	
 }|| j| j || _ d S )Nc                 S   s   g | ]}|  qS r   )
contiguous).0wr   r   r   
<listcomp>)   s     z$NnapiModule.init.<locals>.<listcomp>)r   AssertionErrorr	   preparer
   r   r   torchclasses_nnapiCompilationinit)r   r   r   r   r   r   r    %   s    zNnapiModule.init)r   returnc              	   C   s4  | j d kr| | | j }|d k	s&tdd | jD }t|t| jksLtg }tt|D ]Z}| j| }|dkr|||   q\|dkr||| 	dddd  q\t
dq\||| t|t| jksttt| jD ]F}| j| }|dkrq|dkr&|| 	dddd||< qt
dq|S )	Nc                 S   s   g | ]}t |qS r   )r   Z
empty_like)r   outr   r   r   r   3   s     z'NnapiModule.forward.<locals>.<listcomp>r            zInvalid mem_fmt)r   r$   )r   r    r   r   lenr   rangeappendr   Zpermute	Exceptionrunr   )r   r   r   ZoutsZ
fixed_argsidxfmtr   r   r   forward.   s0    


 




zNnapiModule.forward)__name__
__module____qualname____doc__r   r   r   r   r   __annotations__r   TensornnModuleintr   jitexportr    r-   __classcell__r   r   r   r   r      s   
r   Fc              	   C   s   t | ||||\}}}}}	}
t|||||	}G dd dtjj}||}tj|}ddd tt	|D }|
dk r~d}ndd	d t|
D }|
d
| d| d| d |S )Nc                       s    e Zd ZdZ fddZ  ZS )z5convert_model_to_nnapi.<locals>.NnapiInterfaceWrappera0  NNAPI list-ifying and de-list-ifying wrapper.

        NNAPI always expects a list of inputs and provides a list of outputs.
        This module allows us to accept inputs as separate arguments.
        It returns results as either a single tensor or tuple,
        matching the original module.
        c                    s   t    || _d S r   )r   r   mod)r   r:   r   r   r   r   b   s    
z>convert_model_to_nnapi.<locals>.NnapiInterfaceWrapper.__init__)r.   r/   r0   r1   r   r9   r   r   r   r   NnapiInterfaceWrapperZ   s   r;   z, c                 s   s   | ]}d | V  qdS )Zarg_Nr   r   r+   r   r   r   	<genexpr>i   s     z)convert_model_to_nnapi.<locals>.<genexpr>r   z
retvals[0] c                 s   s   | ]}d | dV  qdS )zretvals[z], Nr   r<   r   r   r   r=   m   s     zdef forward(self, z):
    retvals = self.mod([z])
    return 
)process_for_nnapir   r   r4   r5   r7   scriptjoinr'   r&   define)modelinputs
serializerreturn_shapesuse_int16_for_qint16r	   ser_model_tensorused_weightsr   r   retval_countZnnapi_modelr;   Zwrapper_model_pyZwrapper_modelarg_listZret_exprr   r   r   convert_model_to_nnapiO   s*    rM   c                 C   s   t j| } t|t jr|g}|p,td |d}|| ||\}}}}}	}
t j|t jd}G dd dt j	j
}t j| }dgdd |	D  }|d| ||||||
fS )	N)configrH   )Zdtypec                   @   s   e Zd ZdZdS )z-process_for_nnapi.<locals>.ShapeComputeModulezCode-gen-ed module for tensor shape computation

        module.prepare will mutate ser_model according to the computed operand
        shapes, based on the shapes of args.  Returns a list of output templates.
        N)r.   r/   r0   r1   r   r   r   r   ShapeComputeModule   s   rO   z\def prepare(self, ser_model: torch.Tensor, args: List[torch.Tensor]) -> List[torch.Tensor]:
c                 S   s   g | ]}d | dqS )z    r?   r   )r   liner   r   r   r      s    z%process_for_nnapi.<locals>.<listcomp>r>   )r   r7   freeze
isinstancer3   r   Zserialize_modelZtensorZint32r4   r5   rA   rC   rB   )rD   rE   rF   rG   rH   r
   rJ   r   r   Zshape_compute_linesrK   rI   rO   r	   Zreal_shape_compute_linesr   r   r   r@   u   s0    r@   )NNF)NNF)typingr   r   r   Z torch.backends._nnapi.serializerr   r4   r5   r   rM   r@   r   r   r   r   <module>   s
   H
&