class_docstr: Optimized GroupNorm for NHWC layout with optional Swish/SiLU fusion.
  
  There are two version of CUDA kernels under the hood: one pass and two
  passes. This operator contains a simple heuristic to choose algorithm.
  
  Limitations:
  
  * Designed for 32 groups, also tested with 16 groups, some other number
    of groups can also work but not guaranteed;
  * Supported number of channels C are:
  
      128, 256, 320, 448, 512, 640, 768, 896, 960, 1024, 1280, 1344, 1536,
      1792, 1920, 2048, 2240, 2560, 2688, 3072, 3136, 3584, 4096.
  
    One pass algorithm supports only channels mentioned above. Two pass
    algorithm might automatically support some other channels as well.
  * N/H/W do not have lower (except >0) and upper bound limitations;
  
  All the unsupported cases will be forwarded to PyTorch implementation.
class_docstr_tok: ["Optimized","GroupNorm","for","NHWC","layout","with","optional","Swish\/SiLU","fusion",".","There","are","two","version","of","CUDA","kernels","under","the","hood",":","one","pass","and","two","passes",".","This","operator","contains","a","simple","heuristic","to","choose","algorithm",".","Limitations",":","*","Designed","for","32","groups",",","also","tested","with","16","groups",",","some","other","number","of","groups","can","also","work","but","not","guaranteed",";","*","Supported","number","of","channels","C","are",":","128",",","256",",","320",",","448",",","512",",","640",",","768",",","896",",","960",",","1024",",","1280",",","1344",",","1536",",","1792",",","1920",",","2048",",","2240",",","2560",",","2688",",","3072",",","3136",",","3584",",","4096",".","One","pass","algorithm","supports","only","channels","mentioned","above",".","Two","pass","algorithm","might","automatically","support","some","other","channels","as","well",".","*","N\/H\/W","do","not","have","lower","(","except",">","0",")","and","upper","bound","limitations",";","All","the","unsupported","cases","will","be","forwarded","to","PyTorch","implementation","."]
code: def _check_legality(self, input: Tensor) -> bool:
      is_nhwc = input.is_contiguous(memory_format=torch.channels_last)
      is_legal_groups = self.num_groups in self.SUPPORTED_GROUPS
      is_legal_channels = self.num_channels in self.SUPPORTED_CHANNELS
      is_input_half_or_float_or_bf16 = input.dtype in [
          torch.float16,
          torch.bfloat16,
          torch.float32,
      ]
      is_supported_dtype_combination = (
          not self.affine
          or (input.dtype, self.weight.dtype) in self.SUPPORTED_DTYPES
      )
      is_legal_act = self.act in ["", "silu", "swish"]
  
      if (
          is_nhwc
          and is_input_half_or_float_or_bf16
          and is_supported_dtype_combination
          and is_legal_act
          and self.affine
          and is_legal_groups
          and is_legal_channels
      ):
          return True
      else:
          return False
  
imports: import torch
  import torch.nn.functional
  import torch.nn.init
  import group_norm_cuda
  from torch import Tensor
  from torch.nn.parameter import Parameter
  from torch._dynamo import disable
  from functools import partial
label_desc: Use image node_id 3 for calling the GroupNorm obj's underlying member method code with example usage: obj._check_legality(input) and returns: True, False