class_docstr: 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
code: def forward(self, x, routing_weights):
      B, C, H, W = x.shape
      weight = torch.matmul(routing_weights, self.weight)
      new_weight_shape = (
          B * self.out_channels,
          self.in_channels // self.groups,
      ) + self.kernel_size
      weight = weight.view(new_weight_shape)
      bias = None
      if self.bias is not None:
          bias = torch.matmul(routing_weights, self.bias)
          bias = bias.view(B * self.out_channels)
      # move batch elements with channels so each batch element can be efficiently convolved with separate kernel
      # reshape instead of view to work with channels_last input
      x = x.reshape(1, B * C, H, W)
      if self.dynamic_padding:
          out = conv2d_same(
              x,
              weight,
              bias,
              stride=self.stride,
              padding=self.padding,
              dilation=self.dilation,
              groups=self.groups * B,
          )
      else:
          out = F.conv2d(
              x,
              weight,
              bias,
              stride=self.stride,
              padding=self.padding,
              dilation=self.dilation,
              groups=self.groups * B,
          )
      out = out.permute([1, 0, 2, 3]).view(
          B, self.out_channels, out.shape[-2], out.shape[-1]
      )
  
      # Literal port (from TF definition)
      # x = torch.split(x, 1, 0)
      # weight = torch.split(weight, 1, 0)
      # if self.bias is not None:
      #     bias = torch.matmul(routing_weights, self.bias)
      #     bias = torch.split(bias, 1, 0)
      # else:
      #     bias = [None] * B
      # out = []
      # for xi, wi, bi in zip(x, weight, bias):
      #     wi = wi.view(*self.weight_shape)
      #     if bi is not None:
      #         bi = bi.view(*self.bias_shape)
      #     out.append(self.conv_fn(
      #         xi, wi, bi, stride=self.stride, padding=self.padding,
      #         dilation=self.dilation, groups=self.groups))
      # out = torch.cat(out, 0)
      return out
  
file_path: pytorch-image-models/timm/layers/cond_conv2d.py
imports: import math
  from functools import partial
  import numpy
  import torch
  from torch import nn
  from torch.nn import functional
  from .helpers import to_2tuple
  from .conv2d_same import conv2d_same
  from .padding import get_padding_value
label_desc: Use image node_id 3 for calling the CondConv2d obj's underlying member method code with example usage: obj.forward(x, routing_weights) and returns: out