class_docstr: Applies a GroupLinear transformation layer, as defined `here <https://arxiv.org/abs/1808.09029>`_,
  `here <https://arxiv.org/abs/1911.12385>`_ and `here <https://arxiv.org/abs/2008.00623>`_
  
  Args:
      in_features (int): number of features in the input tensor
      out_features (int): number of features in the output tensor
      n_groups (int): number of groups
      bias (Optional[bool]): use bias or not
      feature_shuffle (Optional[bool]): Shuffle features between groups
  
  Shape:
      - Input: :math:`(N, *, C_{in})`
      - Output: :math:`(N, *, C_{out})`
class_docstr_tok: ["Applies","a","GroupLinear","transformation","layer",",","as","defined","`","here","<","https",":","\/\/arxiv.org\/abs\/1808.09029",">","`","_",",","`","here","<","https",":","\/\/arxiv.org\/abs\/1911.12385",">","`","_","and","`","here","<","https",":","\/\/arxiv.org\/abs\/2008.00623",">","`","_","Args",":","in_features","(","int",")",":","number","of","features","in","the","input","tensor","out_features","(","int",")",":","number","of","features","in","the","output","tensor","n_groups","(","int",")",":","number","of","groups","bias","(","Optional","[","bool","]",")",":","use","bias","or","not","feature_shuffle","(","Optional","[","bool","]",")",":","Shuffle","features","between","groups","Shape",":","-","Input",":",":","math",":","`","(","N",",","*",",","C_","{","in","}",")","`","-","Output",":",":","math",":","`","(","N",",","*",",","C_","{","out","}",")","`"]
code: def _forward(self, x: Tensor) -> Tensor:
      bsz = x.shape[0]
      # [B, N] -->  [B, g, N/g]
      x = x.reshape(bsz, self.n_groups, -1)
  
      # [B, g, N/g] --> [g, B, N/g]
      x = x.transpose(0, 1)
      # [g, B, N/g] x [g, N/g, M/g] --> [g, B, M/g]
      x = torch.bmm(x, self.weight)
  
      if self.bias is not None:
          x = torch.add(x, self.bias)
  
      if self.feature_shuffle:
          # [g, B, M/g] --> [B, M/g, g]
          x = x.permute(1, 2, 0)
          # [B, M/g, g] --> [B, g, M/g]
          x = x.reshape(bsz, self.n_groups, -1)
      else:
          # [g, B, M/g] --> [B, g, M/g]
          x = x.transpose(0, 1)
  
      return x.reshape(bsz, -1)
  
imports: import argparse
  from typing import Optional
  import torch
  from torch import Tensor, nn
  from torch.nn import functional
  from cvnets.layers.base_layer import BaseLayer
  from utils import logger
label_desc: Use image node_id 4 for calling the GroupLinear obj's underlying member method code with example usage: obj._forward(x) and returns: x