class_docstr: Applies an N-dimensional convolution over an input.
  
  Args:
      opts: Command line options.
      in_channels: :math:`C_{out}` from an expected output of size
          :math:`(bs, C_{in}, X_{1}, ..., X_{N})`.
      out_channels: :math:`C_{out}` from an expected output of size
          :math:`(bs, C_{out}, Y_{1}, ..., Y_{N})`.
      kernel_size: Kernel size for convolution. An integer, or tuple of length ``N``.
      stride: Stride for convolution. An integer, or tuple of length ``N``. Default: 1.
      dilation: Dilation rate for convolution. An integer, or tuple of length ``N``.
          Default: ``1``.
      padding: Padding for convolution. An integer, or tuple of length ``N``.
          If not specified, padding is automatically computed based on kernel size and
          dilation range. Default : ``None`` (equivalent to ``[
          int((kernel_size[i] - 1) / 2) * dilation[i] for i in range(N)]``).
      groups: Number of groups in convolution. Default: ``1``.
      bias: Use bias. Default: ``False``.
      padding_mode: Padding mode ('zeros', 'reflect', 'replicate' or 'circular').
          Default: ``zeros``.
      use_norm: Use normalization layer after convolution. Default: ``True``.
      use_act: Use activation layer after convolution (or convolution and normalization).
          Default: ``True``.
      norm_layer: If not None, the provided normalization layer object will be used.
          Otherwise, a normalization object will be created based on config
          ``model.normalization.*`` opts.
      act_layer: If not None, the provided activation function will be used.
          Otherwise, an activation function will be created based on config
          ``model.activation.*`` opts.
  
  Shape:
      - Input: :math:`(bs, C_{in}, X_{1}, ..., X_{N})`.
      - Output: :math:`(bs, C_{out}, Y_{1}, ..., Y_{N})`.
  
  .. note::
      For depth-wise convolution, `groups=C_{in}=C_{out}`.
class_docstr_tok: ["Applies","an","N-dimensional","convolution","over","an","input",".","Args",":","opts",":","Command","line","options",".","in_channels",":",":","math",":","`","C_","{","out","}","`","from","an","expected","output","of","size",":","math",":","`","(","bs",",","C_","{","in","}",",","X_","{","1","}",",","...",",","X_","{","N","}",")","`",".","out_channels",":",":","math",":","`","C_","{","out","}","`","from","an","expected","output","of","size",":","math",":","`","(","bs",",","C_","{","out","}",",","Y_","{","1","}",",","...",",","Y_","{","N","}",")","`",".","kernel_size",":","Kernel","size","for","convolution",".","An","integer",",","or","tuple","of","length","``","N","``",".","stride",":","Stride","for","convolution",".","An","integer",",","or","tuple","of","length","``","N","``",".","Default",":","1.","dilation",":","Dilation","rate","for","convolution",".","An","integer",",","or","tuple","of","length","``","N","``",".","Default",":","``","1","``",".","padding",":","Padding","for","convolution",".","An","integer",",","or","tuple","of","length","``","N","``",".","If","not","specified",",","padding","is","automatically","computed","based","on","kernel","size","and","dilation","range",".","Default",":","``","None","``","(","equivalent","to","``","[","int","(","(","kernel_size","[","i","]","-","1",")","\/","2",")","*","dilation","[","i","]","for","i","in","range","(","N",")","]","``",")",".","groups",":","Number","of","groups","in","convolution",".","Default",":","``","1","``",".","bias",":","Use","bias",".","Default",":","``","False","``",".","padding_mode",":","Padding","mode","(","'zeros","'",",","'reflect","'",",","'replicate","'","or","'circular","'",")",".","Default",":","``","zeros","``",".","use_norm",":","Use","normalization","layer","after","convolution",".","Default",":","``","True","``",".","use_act",":","Use","activation","layer","after","convolution","(","or","convolution","and","normalization",")",".","Default",":","``","True","``",".","norm_layer",":","If","not","None",",","the","provided","normalization","layer","object","will","be","used",".","Otherwise",",","a","normalization","object","will","be","created","based","on","config","``","model.normalization",".","*","``","opts",".","act_layer",":","If","not","None",",","the","provided","activation","function","will","be","used",".","Otherwise",",","an","activation","function","will","be","created","based","on","config","``","model.activation",".","*","``","opts",".","Shape",":","-","Input",":",":","math",":","`","(","bs",",","C_","{","in","}",",","X_","{","1","}",",","...",",","X_","{","N","}",")","`",".","-","Output",":",":","math",":","`","(","bs",",","C_","{","out","}",",","Y_","{","1","}",",","...",",","Y_","{","N","}",")","`",".","..","note",":",":","For","depth-wise","convolution",",","`","groups=C_","{","in","}","=C_","{","out","}","`","."]
code: def __init__(
      self,
      opts: argparse.Namespace,
      in_channels: int,
      out_channels: int,
      kernel_size: Union[int, Tuple[int, ...]],
      stride: Union[int, Tuple[int, ...]] = 1,
      dilation: Union[int, Tuple[int, ...]] = 1,
      padding: Optional[Union[int, Tuple[int, ...]]] = None,
      groups: int = 1,
      bias: bool = False,
      padding_mode: str = "zeros",
      use_norm: bool = True,
      use_act: bool = True,
      norm_layer: Optional[nn.Module] = None,
      act_layer: Optional[nn.Module] = None,
      *args,
      **kwargs,
  ) -> None:
      super().__init__()
  
      if norm_layer is None and use_norm:
          norm_type = getattr(opts, "model.normalization.name")
          if norm_type == "batch_norm":
              norm_type = f"batch_norm_{self.ndim}d"
          norm_layer = get_normalization_layer(
              opts=opts, num_features=out_channels, norm_type=norm_type
          )
      elif norm_layer is not None and use_norm:
          logger.error(
              f"When use_norm is False, norm_layer should be None, but norm_layer={norm_layer} is provided."
          )
  
      if act_layer is None and use_act:
          act_layer = build_activation_layer(
              opts, num_parameters=out_channels
          )
      elif act_layer is not None and use_act:
          logger.error(
              f"When use_act is False, act_layer should be None, but act_layer={act_layer} is provided."
          )
  
      if (
          use_norm
          and any(
              param[0] == "bias"
              for param in norm_layer.named_parameters()
          )
          and bias
      ):
          assert (
              not bias
          ), "Do not use bias when using normalization layers with bias."
  
      if use_norm and isinstance(
          norm_layer, (LayerNorm, LayerNorm2D_NCHW)
      ):
          bias = True
  
      if isinstance(kernel_size, int):
          kernel_size = (kernel_size,) * self.ndim
  
      if isinstance(stride, int):
          stride = (stride,) * self.ndim
  
      if isinstance(dilation, int):
          dilation = (dilation,) * self.ndim
  
      assert isinstance(kernel_size, Tuple)
      assert isinstance(stride, Tuple)
      assert isinstance(dilation, Tuple)
  
      if padding is None:
          padding = (
              int((kernel_size[i] - 1) / 2) * dilation[i]
              for i in range(self.ndim)
          )
  
      if in_channels % groups != 0:
          logger.error(
              "Input channels are not divisible by groups. {}%{} != 0 ".format(
                  in_channels, groups
              )
          )
      if out_channels % groups != 0:
          logger.error(
              "Output channels are not divisible by groups. {}%{} != 0 ".format(
                  out_channels, groups
              )
          )
  
      block = nn.Sequential()
  
      conv_layer = self.module_cls(
          in_channels=in_channels,
          out_channels=out_channels,
          kernel_size=kernel_size,  # type: ignore
          stride=stride,  # type: ignore
          padding=padding,
          dilation=dilation,  # type: ignore
          groups=groups,
          bias=bias,
          padding_mode=padding_mode,
      )
  
      block.add_module(name="conv", module=conv_layer)
  
      self.norm_name = None
      if use_norm:
          block.add_module(name="norm", module=norm_layer)
          self.norm_name = norm_layer.__class__.__name__
  
      self.act_name = None
      if use_act:
          block.add_module(name="act", module=act_layer)
          self.act_name = act_layer.__class__.__name__
  
      self.block = block
      self.in_channels = in_channels
      self.out_channels = out_channels
      self.stride = stride
      self.groups = groups
      self.kernel_size = conv_layer.kernel_size
      self.bias = bias
      self.dilation = dilation
  
imports: import argparse
  from typing import Optional, Tuple, Type, Union
  from torch import Tensor, nn
  from cvnets.layers.activation import build_activation_layer
  from cvnets.layers.base_layer import BaseLayer
  from cvnets.layers.normalization.layer_norm import LayerNorm, LayerNorm2D_NCHW
  from cvnets.layers.normalization_layers import get_normalization_layer
  from utils import logger
label_desc: Use image node_id 3 to create a new _BaseConvNormActLayer object from inherited base classes: BaseLayer with example: obj = _BaseConvNormActLayer(opts, in_channels, out_channels, kernel_size, stride, dilation, padding, groups, bias, padding_mode, use_norm, use_act, norm_layer, act_layer)