U
    d(                     @   sd   d dl mZ d dlmZ d dlmZ ddd	Zdd
dZdddZdddZ	dddZ
dddZdS )    )core)initializers)ParameterTagsN   FNCHWc                 K   s`  g }|r t |ts|g}qN|}n.t |trDt|dks>td|}n
|gd }|d}|d k	r|rv|dkrvtdn|s|dkrtd|rd|d< ||d< |r||d< d	|kr|d	 rd
nd}|p| j }|g}|dkr|t	||  |
| n|
| |t	||  t|	|di f}	t|
|di f}
| jsTt }	t }
| j|d ||	tjd}|r| j|d |g|
tjd}|r|||g}n||g}|d k	r|| || |rd|d< d	|kr|d	= |dkr||d< |r| jj||f||d|S t |tr@| jj||f|d |d |d|S | jj||f||d|S d S )N   zConv support only a 2D kernel.engineCUDNNz?When use_cudnn=True, the only engine you can specify is "CUDNN"z;When use_cudnn=False, the only engine you can specify is ""exhaustive_searchws_nbytes_limitno_biasFTr   
XavierFillConstantFill_w)
param_nameshapeZinitializertags_bfloat16_computer   group)kernelsorderr   )Zkernel_hZkernel_wr   kernelr   )
isinstancelistlenAssertionErrorget
ValueErrornetNextNameappendintextendr   Zupdate_initializerinit_paramsZExternalInitializerZcreate_paramr   WEIGHTBIASConv)modelZis_ndblob_inblob_outdim_indim_outr   weight_init	bias_initWeightInitializerBiasInitializerr   transform_inputs	use_cudnnr   cudnn_exhaustive_searchr   r   kwargsr   Zrequested_engineuse_biasweight_shapeweightbiasinputs r;   >/tmp/pip-unpacked-wheel-ua33x9lu/caffe2/python/helpers/conv.py	_ConvBase   s    




    


r=   c                 K   s<   |dkst dt| d|||||||||	|
|fd|i|S )zBN-dimensional convolution for inputs with NCHW storage order.
    r   z'ConvNd only supported for NCHW storage.Tr   )r   r=   )r)   r*   r+   r,   r-   r   r.   r/   r0   r1   r   r2   r   r5   r;   r;   r<   conv_nd   s        r>   c                 K   s$   t | d|||||||||	|
|f|S )z2-dimensional convolution.
    F)r=   )r)   r*   r+   r,   r-   r   r.   r/   r0   r1   r   r2   r5   r;   r;   r<   conv   s        r?   c                 K   s2  |r|ndi f}|r|ndi f}|p,| j  }|	dkrB||||gn
||||g}| jr| j|d g |d fd|i|d }| j|d g |d fd|gi|d }n$t|d | j}t|d | j}| |tj	 | |tj
 |rd	|d
< |
|d< |r||d< | j j|||g|f||	d|S )zConvTranspose.
    r   r   r   r   r   r   r   r   r	   r   r
   r   r   )r    r!   r%   param_init_net__getattr__r   ScopedBlobReferenceAddParameterr   r&   r'   ZConvTranspose)r)   r*   r+   r,   r-   r   r.   r/   r3   r   r4   r   r5   r7   r8   r9   r;   r;   r<   conv_transpose   s`    
  rD   c	           
      K   s"   t | |||||f|||d|	S )zGroup Convolution.

    This is essentially the same as Conv with a group argument passed in.
    We specialize this for backward interface compatibility.
    )r.   r/   r   )r?   )
r)   r*   r+   r,   r-   r   r.   r/   r   r5   r;   r;   r<   
group_conv   s     rE   c                    sF  |r|ndi f}|r|ndi f}d|kr4|d r4dnd}|	rhd|d< ||d< |rh||d	<  rht d
| rxt d| jj| fddtD fddtD |
d}|
dkr|  ||gn| || g}dd |D }g }tD ] }| jrx| j|d g  d|  fd|i|d }|r| j|d g  d|  fdt| gi|d }n2t	 d|  | j}|rt	 d|  | j}| 
|tj |r| 
|tj |r||g}n|g}d|kr|d= ||| j| d|  f||
d| q| jj| d  d g|
d\}}|S )zGroupConvolution's deprecated interface.

    This is used to simulate a group convolution via split and concat. You
    should always use the new group convolution in your new code.
    r   r   r   FTr	   r   r
   r   z$dim_in should be divisible by group.z%dim_out should be divisible by group.c                    s    g | ]}d   d t | qS )_Z_gconv_split_)str.0i)r+   r;   r<   
<listcomp>0  s     z)group_conv_deprecated.<locals>.<listcomp>c                    s   g | ]}t   qS r;   r#   rH   )r,   r   r;   r<   rK   1  s     )Z
dimensionsr   r   c                 S   s   g | ]}t |qS r;   rL   )rI   vr;   r;   r<   rK   ;  s     r   z_gconv_%d_wr   r   z_gconv_%d_bz	_gconv_%dr   rF   Z_concat_dims)r   )r   r    Z
DepthSplitranger%   r@   rA   r#   r   rB   rC   r   r&   r'   r"   r(   ZConcat)r)   r*   r+   r,   r-   r   r.   r/   r   r3   r   r4   r   r5   r6   Zsplitted_blobsr7   Z
conv_blobsrJ   r8   r9   r:   concatZconcat_dimsr;   )r+   r,   r   r<   group_conv_deprecated  s    


 
 


	

rP   )NNNNr   NFr   FNF)NNNNr   Nr   )NNNNr   N)NNFr   FN)NNr   )NNr   Fr   FN)Zcaffe2.pythonr   Zcaffe2.python.modelingr   Z%caffe2.python.modeling.parameter_infor   r=   r>   r?   rD   rE   rP   r;   r;   r;   r<   <module>   sb   
           
        
      
      
A   
       