class_docstr: Fused operation: scaling + mask + softmax
  
  Arguments:
      input_in_fp16: Flag to indicate if input in fp16 data format.
      input_in_bf16: Flag to indicate if input in bf16 data format.
      attn_mask_type: Attention mask type (pad or causal)
      scaled_masked_softmax_fusion: Flag to indicate user want to use softmax fusion
      mask_func: Mask function to be applied.
      softmax_in_fp32: If True, softmax in performed at fp32 precision.
      scale: Scaling factor used in input tensor scaling.
code: def is_kernel_available(self, mask, b, np, sq, sk):
      attn_batches = b * np
  
      if (
          self.scaled_masked_softmax_fusion  # user want to fuse
          and self.input_in_float16  # input must be fp16
          and mask is not None  # mask tensor must not be None
          and 16 < sk <= 2048  # sk must be 16 ~ 2048
          and sq % 4 == 0  # sq must be divisor of 4
          and attn_batches % 4 == 0  # np * b must be divisor of 4
      ):
          if 0 <= sk <= 2048:
              batch_per_block = self.get_batch_per_block(sq, sk, b, np)
  
              if self.attn_mask_type.value > 1:
                  if attn_batches % batch_per_block == 0:
                      return True
              else:
                  if sq % batch_per_block == 0:
                      return True
      return False
  
imports: import enum
  import torch
  import torch.nn
  from colossalai.kernel.op_builder.scaled_masked_softmax import ScaledMaskedSoftmaxBuilder
  from colossalai.kernel.op_builder.scaled_upper_triangle_masked_softmax import ScaledUpperTrainglemaskedSoftmaxBuilder
label_desc: Use image node_id 3 for calling the FusedScaleMaskSoftmax obj's underlying member method code with example usage: obj.is_kernel_available(mask, b, np, sq, sk) and returns: False, True, True