a
    ==ic                     @   s<  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	m
Z
 d dlmZmZmZ d dlmZ e  edZeej dd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd ZG dd deZdd Z dd Z!dd Z"dd  Z#e$d!d"d# Z%e$d$d%d& Z&e$d'd(d) Z'd*d+ Z(e$d,d-d. Z)e$d/d0d1 Z*e$d2d3d4 Z+e$d5d6d7 Z,e$d8d9d: Z-e$d;d<d= Z.e$d>d?d@ Z/e$dAdBdC Z0e$dDdEdF Z1e$dGdHdI Z2e$dJdKdL Z3e$dMdNdO Z4e$dPdQdR Z5e$dSdTdU Z6e$dVdWdX Z7e$dYdZd[ Z8e$d\d]d^ Z9e$d_d`da Z:e$dbdcdd Z;e$dedfdg Z<e$dhdidj Z=e$dkdldm Z>e$dndodp Z?e$dqdrds Z@e$dtdudv ZAeBdwkr8e jCdxdyZDeDjEdzd{d| eDjEd}d~d| eDjEdddd eDjEdddd eDjEddddd eDjEdddeFg d eDG ZHe
I ZJe
I ZKeHjLZMeHjNZOeHjPZQeHjRZSeTeM ZUeVeUW eJ W d   n1 s0    Y  eTeOdZUeKXeUW  W d   n1 s0    Y  e eJeKdeHjYeHjZd\Z[Z\e[j]d  j^d  Z_e[j]d j`d  Zae[j_be_g e[j_bdd e\jcD  e[jabeag e!e\e_ZPeTeSdZUeUde[e  W d   n1 s0    Y  eTeSd dZUeUdefe[ W d   n1 s0    Y  eTeQdZUeUdePe  W d   n1 s.0    Y  dS )    N)
caffe2_pb2caffe2_legacy_pb2)	caffe_pb2)coreutils	workspace)text_formatZcaffe_translatorc                    s   | dr|j| jkrdS | dr4| j|jk r4dS | drN| j|jkrNdS tt| j t|jrt	 fdd|jD rdS t|j
rt	 fdd|j
D rdS dS )	z@A function that reproduces Caffe's StateMeetsRule functionality.phaseF	min_level	max_levelc                    s   g | ]}| vqS  r   .0sZcurr_stagesr   o/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/caffe2/python/caffe_translator.py
<listcomp>       z#_StateMeetsRule.<locals>.<listcomp>c                    s   g | ]}| v qS r   r   r   r   r   r   r   !   r   T)HasFieldr	   levelr
   r   setlistZstagelenanyZ	not_stage)stateruler   r   r   _StateMeetsRule   s    ""r   c                    sV   t |jdk}|t fdd|jD  M }t |jrR|t fdd|jD O }|S )z@A function that reproduces Caffe's inclusion and exclusion rule.r   c                    s   g | ]}t  |qS r   r   r   r   	net_stater   r   r   +   r   z"_ShouldInclude.<locals>.<listcomp>c                    s   g | ]}t  |qS r   r   r   r   r   r   r   .   r   )r   includer   exclude)r    layerretr   r   r   _ShouldInclude'   s
    
r%   c                 C   s   i }t j }|jD ]}||jt| q| j	d j
d }||| tt| j	D ]B}| j	| }	||	  ||v r`|	jd }
||
}|j||< q`|S Nr   r   C	Workspaceprotoscreate_blobnamefeedr   Caffe2TensorToNumpyArrayopinputranger   _run_operatorSerializeToStringoutput
fetch_blobshape)net
net_paramsdummy_inputlegacy_pad_opsdim_mapwsparamexternal_inputiop_defr4   Zblob_legacyr   r   r   _GetLegacyDims2   s     




rA   c                    sH   i }g d}d v }|r2|D ]} d j ||< qn fdd|D }|S )N)pad_lpad_tpad_rpad_bpadc                    s   i | ]}| | j qS r   r?   )r   xarg_mapr   r   
<dictcomp>M   r   z%_GetLegacyPadArgs.<locals>.<dictcomp>rG   )r@   rJ   padskeysis_padkr   rI   r   _GetLegacyPadArgsE   s    rP   c                 C   s(  |\}}}}|\}	}
}}||	ks$J ||
ks0J d|v }||ksJ||kr$||d krh|d  d7  < n||kr|t d||||d kr|d  d7  < n||krt d|||r| j|d  g }| D ]&}t }||_|| |_|| q| j	| n| D ]}|| || _qd S )NrF      rE   z!Unexpected dimensions for height:rD   z Unexpected dimensions for width:)
	ExceptionargremoverM   r   Argumentr,   r?   appendextend)r@   rJ   rL   dim1dim2Zn1c1Zh1Zw1Zn2c2Zh2Zw2rN   argsr,   rS   r   r   r   _AdjustDimsQ   s2    
r]   c                 C   s  g }t t| jD ]@}| j| }td|jr|jD ]}|jdkr4||  qq4q|r|\}}}	}
t	j
|||	|
t	j}t| |||}tj }| jd jd }||| |jD ]}||jt| qt t| jD ]}| j| }||v ri }|jD ]}|||j< qt||}t t|jD ]*}|j| }|jdkr6|j|=  qbq6|jd }|d }||jd< ||  ||}||jd< || }|j}t||||| ||  q| S )Nz0^(Conv|ConvTranspose|MaxPool|AveragePool)(\dD)?$
legacy_padr   Z
_nonlegacy)r1   r   r/   rematchtyperS   r,   rV   nprandomrandnastypefloat32rA   r   r(   r)   r0   r+   Z	feed_blobr*   r   r.   rP   r4   r2   r3   r5   r6   r]   )r7   r8   
input_dimsr:   r?   r@   rS   nchwr9   r;   r<   r>   r=   rJ   rL   jr4   Znonlegacy_outputZblob_nonlegacyrX   rY   r   r   r   _RemoveLegacyPadn   sX    















rm   c                 C   s   i }t j }|jD ]}||jt| q| j	d j
d }||| tt| j	D ]<}| j	| }||  |jD ]}	||	}
|
j||	< qq`|S r&   r'   )r7   r8   r9   r;   r<   r=   r>   r?   r@   r4   blobr   r   r   _GetBlobDimMap   s    




ro   c                 C   sL   g }| j r| j }n6| jr&| jd j}n"| jd jjrH| jd jjd j}|S r&   )Z	input_dimZinput_shapedimr#   Zinput_paramr6   )	caffe_netrg   r   r   r   _GetInputDims   s    rr   c                   @   s6   e Zd Zi Zedd Zedd Zed	ddZdS )
TranslatorRegistryc                    s    fdd}|S )z.A decorator for registering gradient mappings.c                    s   |  j < | S N)	registry_)funcclsop_namer   r   Wrapper   s    
z,TranslatorRegistry.Register.<locals>.Wrapperr   )rx   ry   rz   r   rw   r   Register   s    zTranslatorRegistry.Registerc                 K   sn   z$| j |j |||fi |\}}W n" tyF   tdt| Y n0 |d u rTg }t|turf|g}||fS )Nz+No translator registered for layer: %s yet.)ru   ra   KeyErrorstrr   )rx   r#   pretrained_blobsis_testkwargs	caffe_opsparamsr   r   r   TranslateLayer   s    
z!TranslatorRegistry.TranslateLayerFNc              	      sH  |d u rt  n|}t }|j|_t }t|jdkrBtd|sNt	|}|j
D ]ʉ t| svtd j qTtd j  fdd|j
D  fdd|jD  }	t|	dkrtd	n&t|	dkrd
d |	d jD }
ng }
| j |
||||d\}}|j| |j| qT|r@|s4J dt|||}||fS )Nr   zuI think something is wrong. This translation script only accepts new style layers that are stored in the layer field.z(Current net state does not need layer {}zTranslate layer {}c                    s   g | ]}|j  j kr|qS r   r,   r   lr#   r   r   r      s   z5TranslatorRegistry.TranslateModel.<locals>.<listcomp>c                    s   g | ]}|j  j kr|qS r   r   r   r   r   r   r      s   rQ   z0huh? more than one pretrained layer of one name?c                 S   s   g | ]}t |qS r   )r   ZCaffeBlobToNumpyArray)r   rn   r   r   r   r     s   )r7   r8   rg   z.Please specify input_dims to remove legacy_pad)r   ZNetStater   NetDefr,   ZTensorProtosr   Zlayers
ValueErrorrr   r#   r%   loginfoformatZblobsr   r/   rW   r*   rm   )rx   rq   Zpretrained_netr   r    remove_legacy_padrg   r7   r8   Zpretrained_layersr~   	operatorsr   r   r   r   TranslateModel   sX    




z!TranslatorRegistry.TranslateModel)FNFN)__name__
__module____qualname__ru   classmethodr{   r   r   r   r   r   r   rs      s   
	
    rs   c                  O   s   t j| i |S rt   )rs   r   )r\   r   r   r   r   r     s    r   c              
   C   s   t  }| jD ]Z}t|jdkr(tdtjdg |jgt	
dt|jt	
d|jgd}|j|g q|jtjdg |gdgd	g |S )
aa  Takes the net_params returned from TranslateModel, and wrap it as an
    init net that contain GivenTensorFill.

    This is a very simple feature that only works with float tensors, and is
    only intended to be used in an environment where you want a single
    initialization file - for more complex cases, use a db to store the
    parameters.
    r   z.Only float tensors are supported in this util.ZGivenTensorFillr6   values)rS   ZConstantFillrQ   )r6   )r   r   r*   r   Z
float_dataRuntimeErrorr   CreateOperatorr,   r   MakeArgumentr   dimsr/   rW   )r8   Z
input_nameinit_netZtensorr/   r   r   r   ConvertTensorProtosToInitNet  s    	

 r   c                 C   s.   t  }||_|j| j |j| j |S )zBA simple translate interface that maps the layer input and output.)r   OperatorDefra   r0   rW   bottomr4   top)r#   Zcaffe2_typeZ	caffe2_opr   r   r   BaseTranslate6  s
    r   c                 C   s   | j t||g dS )z*Makes an argument based on the value type.N)rS   rW   r   r   )r/   keyvaluer   r   r   AddArgument?  s    r   ZInputc                 K   s   g g fS rt   r   r#   r~   r   r   r   r   r   TranslateInputH  s    r   Z	VideoDatac                 K   s   g g fS rt   r   r   r   r   r   TranslateVideoDataM  s    r   ZDatac                 K   s   g g fS rt   r   r   r   r   r   TranslateDataR  s    r   c                 C   s  z~t | jdks,t | jdks,t | jdkr4tdt | jrH| jd nd}t | jr`| jd nd}t | jrx| jd nd}W n$ ty   | j}| j}| j}Y n0 | ds| drt|d| j t|d| j	 nt|d| | ds| drP| j
| jkrt|d	| j
 n8t|d
| j
 t|d| j
 t|d| j t|d| j nt|d	| | dst| drt|d| j t|d| j nt|d| d S )NrQ   zRTranslator currently does not support non-conventional pad/kernel/stride settings.r   stride_hstride_wstridepad_hpad_wrF   rC   rE   rB   rD   kernel_hkernel_wkernel)r   r   kernel_sizerF   NotImplementedError	TypeErrorr   r   r   r   r   r   r   r   )r=   caffe_opr   rF   r   r   r   r   _TranslateStridePadKernelHelperY  s<    r   ZConvolution3Dc           
      K   s   | j }t| d}|jd }|j|d  t|d|j|j|jg t|d|j|j	|j	g d}d}t
|drr|j}t
|dr|j}t|d|||gd	  t|d |d g}	t|d	kr|j|d
  |	t|d  |d
  ||	fS )NConvr   _wkernelsstridestemporal_padrF   rL      _brQ   )Zconvolution3d_paramr   r4   r0   rV   r   kernel_depthr   temporal_strider   hasattrr   rF   r   NumpyArrayToCaffe2Tensorr   flatten)
r#   r~   r   r   r=   r   r4   r   spatial_padr   r   r   r   TranslateConvNd  s>    



r   ZConvolutionc                 K   s  | j }t| d}|jd }|j|d  t|| t|d |d g}t|dkr|j|d  |t|d 	 |d  |j
dkrt|d|j
 t|jdkrt|jdkrt|d|jd  n2t|jdkrt|d	|jd  t|d
|jd  ||fS )Nr   r   r   r   r   rQ   groupdilationZ
dilation_hZ
dilation_w)convolution_paramr   r4   r0   rV   r   r   r   r   r   r   r   r   )r#   r~   r   r   r=   r   r4   r   r   r   r   TranslateConv  s.    



r   ZDeconvolutionc           	      K   s   | j }|jdkrtdt| d}|jd }t|| |j|d g t|dd t	
|d |d }|jrt	
|d  |d }|j|d g |||gfS ||gfS d S )	NrQ   z:Translator currently does not support group deconvolution.ZConvTransposer   r   orderNCHWr   )r   r   r   r   r4   r   r0   rW   r   r   r   Z	bias_termr   	r#   r~   r   r   r=   r   r4   weightbiasr   r   r   TranslateDeconv  s$    



r   ZCropc                    sf  |d |d |d   }}}|\}}}	}
t j|||	|
t j}t|||}| j}|j|j }t	| d}|j
d }||  g g  }}t|| }tdksJ dt|D ]}|d |d q fd	d
t||D }|| |d gt|  t }|j
|j
d g |j|j |j|j |j|_t|d| t|d| |g fS )Nr7   r8   rg   SlicerQ   z@Caffe Translator for Crop only works for offset     of 1 for nowr   c                    s    g | ]}t d   |  qS )r   )int)r   r?   Zinput_1_dimoffsetsr   r   r     r   z!TranslateCrop.<locals>.<listcomp>startsends)rb   rc   rd   re   rf   ro   Z
crop_paramaxisoffsetr   r0   r   r1   rV   rW   r   r   r4   rS   ra   r   )r#   r~   r   r   r7   r8   rg   rh   ri   rj   rk   r9   r;   r=   r   r   Zinput_1r   r   r   _Z
end_offsetr/   r   r   r   TranslateCrop  s4    




r   ZReLUc                 K   s   t | dg fS )NZRelur   r   r   r   r   TranslateRelu  s    r   ZPoolingc                 K   s   | j }|jtjjkr t| d}n|jtjjkr8t| d}t|| t|dd z
|j	}W n t
yn   d}Y n0 |st|dtj |jrt|dd |g fS )	NMaxPoolAveragePoolr   r   Fr^   global_poolingrQ   )Zpooling_parampoolr   ZPoolingParameterMAXr   AVEr   r   Ztorch_poolingAttributeErrorr   ZCAFFE_LEGACY_POOLINGr   )r#   r~   r   r   r=   r   Zis_torch_poolingr   r   r   TranslatePool  s$    

	

r   Z	Pooling3Dc                 K   s   | j }|jtjjkr t| d}n|jtjjkr8t| d}t|dd t|d|j|j	|j	g t|d|j
|j|jg d}d}t|dr|j}t|d	r|j}t|d
|||gd  |g fS )Nr   r   r   r   r   r   r   r   rF   rL   r   )Zpooling3d_paramr   r   ZPooling3DParameterr   r   r   r   r   r   r   r   r   r   rF   )r#   r~   r   r   r=   r   r   r   r   r   r   TranslatePool3D  s0    


r   LRNc                 K   s   t | d}|jd|jd  d g | j}|jtjjkrBtdt	|dt
|j t	|dt|j t	|dt|j t	|d	t|j t	|d
d |g fS )Nr   r   r   _scalez8Does not support norm region other than across channels.sizealphabetar   r   r   )r   r4   rW   Z	lrn_paramZnorm_regionr   ZLRNParameterZACROSS_CHANNELSr   r   r   Z
local_sizefloatr   r   rO   r#   r~   r   r   r   r=   r   r   r   TranslateLRN7  s    
r   ZInnerProductc           	      K   s  | j }z|jdks|jr tdW n ty4   Y n0 t| d}|jd }|j|d |d g |d j	dvrxtd|d j	d	krt
|d jd d
 ddgkrtdt|d j t|d d|d jd |d }t|d  |d }|||gfS )NrQ   zWe don't have testing case for non-default axis and transpose cases yet so we are disabling it for now. If you have a model with this, please do send us your model for us to update this support, and you are more than welcome to send a PR for this.FCr   r   r   )r      zUnexpected weight ndim.r   r   z_If pretrained blob has 4 dims (old-style Caffe), the first two should be of value 1, but I got r   )Zinner_product_paramr   Z	transposer   r   r   r4   r0   rW   ndimr   r6   r}   r   r   Zreshaper   r   r   r   r   TranslateInnerProductG  s:    

r   Dropoutc                 K   sR   t | d}|jd|jd  d g | j}t|d|j |rJt|dd |g fS )Nr   r   r   Z_maskratior   rQ   )r   r4   rW   Zdropout_paramr   Zdropout_ratior   r   r   r   TranslateDropoutk  s    
r   Softmaxc                 K   s   t | d}|g fS )Nr   r   r#   r~   r   r   r   r   r   r   TranslateSoftmaxv  s    
r   ZSoftmaxWithLossc                 K   sp   t d| jd g| jd d }t d|jd | jd g| jd d }t d|jd | jd }|||gg fS )Nr   r   Z_translator_autogen_softmaxZLabelCrossEntropyrQ   Z_translator_autogen_xentZAveragedLoss)r   r   r   r4   r   )r#   r~   r   r   Z
softmax_opZxent_opZloss_opr   r   r   TranslateSoftmaxWithLoss|  s    r   Accuracyc                 K   s.   t | d}| jjdkr&t|d| jj |g fS )Nr   rQ   top_k)r   Zaccuracy_paramr   r   r   r   r   r   TranslateAccuracy  s    
r   Concatc                 K   s:   t | d}|jd|jd  d g t|dd |g fS )Nr   r   r   _dimsr   r   )r   r4   rW   r   r   r   r   r   TranslateConcat  s    
r   ZTanHc                 K   s   t | d}|g fS )NZTanhr   r   r   r   r   TranslateTanH  s    
r   InstanceNormc                 K   st   t | d}|jd }t|d  |d }t|d  |d }|j|d |d g t|dd |||gfS )Nr   r   r   rQ   r   r   r   )r   r4   r   r   r   r0   rW   r   )r#   r~   r   r   r   r4   r   r   r   r   r   TranslateInstanceNorm  s    

r   Z	BatchNormc                 K   s  t | d}|jd }| j}t|d| t|d|j t|dd |j|d |d |d	 |d
 g |s|j|d	 |d
 |d |d g |d jd }|d d dkrt	d|d d  |d  |d	 }t	d|d d  |d  |d
 }	nt
dt|dkr<t	|d  |d }
t	|d  |d }nPd|d d< t|d |f|d< t	|d |d }
t	t|d |d }||
|||	gfS )NZ	SpatialBNr   r   epsilonr   r   r   Z_biasZ_meanZ_varZ_saved_meanZ
_saved_varr   g      ?rQ   zscalar is zero.   r   )r   r4   Zbatch_norm_paramr   Zepsr0   rW   r6   r   r   r   r   r   rb   ZtileZ
zeros_like)r#   r~   r   r   r   r4   r=   Z
n_channelsmeanvarscaler   r   r   r   TranslateBatchNorm  sh    



r  ZEltwisec                 K   s4   | j }t|js|jdkr"tdt| d}|g fS )NrQ   z(This eltwise layer is not yet supported.ZSum)Zeltwise_paramr   Zcoeff	operationr   r   r#   r~   r   r   r=   r   r   r   r   TranslateElementWise  s
    
r  ZScalec                 K   s  t | d}| j}t|d|j t|dd t|jdkr\|jdkrLtd|jd }|d }|j	| g }|	t
|d  | d }	t|dkrnt|d	kr t|}	d
|	_|d }
|d }|jd d = |j	| |	jd d = |	j	| |	j	|
 |	t
|d  |
 ntd|g}|	r>|	|	 t|t|ksTJ ||fS t|jd	krvtdntdd S )NZMulr   	broadcastTrQ   z$This path has not been verified yet.r   Zscale_wr   AddZscale_b	_internalz.Unexpected number of pretrained blobs in ScalezUnexpected number of inputs.)r   scale_paramr   r   r   r0   Znum_axesr   r4   rV   r   r   r   copydeepcopyra   )r#   r~   r   r   Zmul_opr	  r4   Zmul_op_paramweightsZadd_opZadd_op_paramZinternal_blobr   r   r   r   TranslateScale  sN    





r  Reshapec                 K   sB   t | d}|jd|jd  d  | j}t|d|jj |g fS )Nr  r   r   r   r6   )r   r4   rV   r0   reshape_paramr   r6   rp   )r#   r~   r   r   r   r  r   r   r   TranslateReshape$  s
    
r  Flattenc                 K   s\   | j }|jdkrtd|jdkr.t| d}n&|jdkrDt| d}ntd|j|g fS )Nr   z)flatten_param.end_axis not supported yet.r   ZFlattenToVecrQ   r  z,Not supported yet for flatten_param.axis {}.)Zflatten_paramZend_axisr   r   r   r   r  r   r   r   TranslateFlatten-  s    



r  Sigmoidc                 K   s   t | d}|g fS )Nr  r   r   r   r   r   TranslateSigmoid?  s    
r  Z
ROIPoolingc                 K   s   t | d}t|dd |r(t|d| n|j|jd d  | j}|dr\t|d|j |drtt|d|j |d	rt|d	|j |g fS )
NZRoIPoolr   r   r   r   Z	_argmaxespooled_hpooled_wspatial_scale)	r   r   r4   rV   Zroi_pooling_paramr   r  r  r  r   r   r   r   TranslateROIPoolingE  s    



r  ZPReLUc                 K   sD   t | d}|jd }|j|d g t|d |d }||gfS )NZPRelur   Z_Slope)r   r4   r0   rW   r   r   )r#   r~   r   r   r   r4   Zsloper   r   r   TranslatePRelu[  s
    

r  Z	Reductionc                 K   sp   | j }|jtjjkr t| d}n"|jtjjkr:t| d}ntd|jdkrTtd|j }t	|d| |g fS )NZReduceBackSumZReduceBackMeanzNot yet supportedr   num_reduce_dim)
Zreduction_paramr  r   ZReductionParameterZSUMr   ZMEANr   r   r   )r#   r~   r   r   r=   r   r  r   r   r   TranslateReductione  s    
r  __main__z>Utilitity to convert pretrained caffe models to Caffe2 models.)description	prototextzCaffe prototext.)help
caffemodelzCaffe trained model.z
--init_netzCaffe2 initialization net.zinit_net.pb)r  defaultz--predict_netzCaffe2 prediction net.zpredict_net.pbz--remove_legacy_padzSRemove legacy pad                         (Only works for nets with one input blob)
store_trueF)r  actionr!  z--input_dimszDimension of input blob+)r  nargsra   r!  rbT)r   r   rg   r   c                 C   s   g | ]
}|j qS r   r   )r   r=   r   r   r   r     r   r   wbtxtrk   )gargparser
  loggingr_   numpyrb   Zcaffe2.protor   r   Zcaffe.protor   Zcaffe2.pythonr   r   r   Zgoogle.protobufr   basicConfig	getLoggerr   setLevelINFOr   r%   rA   rP   r]   rm   ro   rr   objectrs   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   ArgumentParserparseradd_argumentr   
parse_argsr\   ZNetParameterZcaffenetZcaffenet_pretrainedr  Zinput_protor   Zinput_caffemodelr   Zoutput_init_netZpredict_netZoutput_predict_netopenfZMergereadZParseFromStringr   rg   r7   Zpretrained_paramsr/   r0   r>   r4   Zexternal_outputrW   r*   writer3   r}   r   r   r   r   <module>   s   
7W		


*
"







#








5


3




	



0.

..