a
    dO                     @   s   d Z ddlZddlmZ ddl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s4| jd ks4| jd |kr<tdtD ]}| |   qDdS )zCondConv initializer function.   r   r   z<CondConv variables must have shape [num_experts, num_params]N)npprodlenshape
ValueErrorrangeview)weightZ
num_paramsiexpert_shapeinitializernum_experts `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/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 }qtjt| j|| _|r| 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   	ParameterZTensorr   
bias_shaper$   Zregister_parameterreset_parameters)selfr   r   r'   r"   r(   r#   r)   r$   r   Zpadding_valZis_padding_dynamicZ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rt| jdd  }dt| }t ttjj| |d| j| j}|| j
 d S )N   )ar   )r4   b)r   r   r   initZkaiming_uniform_mathsqrtr   r*   r   r$   r
   r   Zuniform_r-   )r/   Zinit_weightZfan_inboundZ	init_biasr   r   r   r.   I   s    

zCondConv2d.reset_parametersc              	   C   s   |j \}}}}t|| j}|| j | j| j f| j }||}d }	| j	d urnt|| j	}	|	|| j }	|
d|| ||}| jrt|||	| 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$   Zreshaper   r   r"   r(   r#   FZconv2dZpermute)r/   xZrouting_weightsBCHWr   Znew_weight_shaper$   outr   r   r   forwardT   s(    

(zCondConv2d.forward)r   r   r    r   r   Fr!   )	__name__
__module____qualname____doc__Z__constants__r&   r.   rD   __classcell__r   r   r1   r   r   "   s     r   )rH   r7   	functoolsr   numpyr
   r+   r   Ztorch.nnr   r=   Zhelpersr   r   r(   r   r   Moduler   r   r   r   r   <module>   s   