o
    پi@                     @   sz   d Z ddlZddlmZ ddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ dd	lmZ d
d ZG dd dejZdS )z PyTorch Conditionally Parameterized Convolution (CondConv)

Paper: CondConv: Conditionally Parameterized Convolutions for Efficient Inference
(https://arxiv.org/abs/1904.04971)

Hacked together by / Copyright 2020 Ross Wightman
    N)partial)nn)
functional   )	to_2tuple)conv2d_same)get_padding_valuec                    s    fdd}|S )Nc                    s`   t  }t| jdks| jd ks| jd |krtdtD ]}| |   q"dS )zCondConv initializer function.   r   r   z<CondConv variables must have shape [num_experts, num_params]N)mathprodlenshape
ValueErrorrangeview)weight
num_paramsiexpert_shapeinitializernum_experts K/home/ubuntu/.local/lib/python3.10/site-packages/timm/layers/cond_conv2d.pycondconv_initializer   s   
z6get_condconv_initializer.<locals>.condconv_initializerr   )r   r   r   r   r   r   r   get_condconv_initializer   s   	r   c                       s>   e Zd ZdZg dZ		d fdd		Zd
d Zdd Z  ZS )
CondConv2daO   Conditionally Parameterized Convolution
    Inspired by: https://github.com/tensorflow/tpu/blob/master/models/official/efficientnet/condconv/condconv_layers.py

    Grouped convolution hackery for parallel execution of the per-sample kernel filters inspired by this discussion:
    https://github.com/pytorch/pytorch/issues/17983
    )in_channelsout_channelsdynamic_padding   r    F   c
                    s   t t|   || _|| _t|| _t|| _t||||d\}
}|| _	t|
| _
t|| _|| _|	| _| j| j| j f| j | _d}| jD ]}||9 }qFtjt| j|| _|rn| jf| _tjt| j| j| _n| dd  |   d S )N)stridedilationr   bias)superr   __init__r   r   r   kernel_sizer#   r   r   paddingr$   groupsr   weight_shapetorchr   	ParameterTensorr   
bias_shaper%   register_parameterreset_parameters)selfr   r   r(   r#   r)   r$   r*   r%   r   padding_valis_padding_dynamicweight_num_paramwd	__class__r   r   r'   *   s.   







zCondConv2d.__init__c                 C   s   t ttjjtdd| j| j}|| j	 | j
d urCt| jdd  }dt| }t ttjj| |d| j| j}|| j
 d S d S )N   )ar   )r:   b)r   r   r   initkaiming_uniform_r
   sqrtr   r+   r   r%   r   uniform_r/   )r2   init_weightfan_inbound	init_biasr   r   r   r1   H   s   

zCondConv2d.reset_parametersc              	   C   s   |j \}}}}t|| j}|| j | j| j f| j }||}d }	| j	d ur7t|| j	}	|	|| j }	|
d|| ||}| jrVt|||	| j| j| j| j| d}
ntj|||	| j| j| j| j| d}
|
g d|| j|
j d |
j d }
|
S )Nr   )r#   r)   r$   r*   )r   r   r	   r    )r   r,   matmulr   r   r   r*   r(   r   r%   reshaper   r   r#   r)   r$   Fconv2dpermute)r2   xrouting_weightsBCHWr   new_weight_shaper%   outr   r   r   forwardS   s(   

(zCondConv2d.forward)r    r   r!   r   r   Fr"   )	__name__
__module____qualname____doc____constants__r'   r1   rS   __classcell__r   r   r7   r   r   !   s    r   )rW   r
   	functoolsr   r,   r   torch.nnr   rH   helpersr   r   r)   r   r   Moduler   r   r   r   r   <module>   s    