class_docstr: Implements Conv3d + Bn + Activation for pointwise layers.
  The conv layer has fixed kernel_size = (1,1,1),
  groups = 1, padding = 0, stride = 1, dilation = 1.
  
                        Input
                          |
                          ↓
                      conv3d (1x1x1)
                          ↓
                      BatchNorm (optional)
                          ↓
                      Activation
  
  Conv3dPwBnAct is in original form (for training) once instantiated. User can
  call convert() method to convert it into deployable form for deployment.
  
  convert_flag variable is to record whether the Conv3dPwBnAct instance
  has been converted; Conv3dPwBnAct is in original form if convert_flag is false,
  while it is in deployable form if convert_flag is true.
  
  Current implementation of this layer in QNNPACK is very efficient.
  Args:
      in_channels (int): number of input channels for conv3d 1x1x1.
      out_channels (int): number of output channels for conv3d 1x1x1.
      bias (bool): if true, use bias for conv.
      activation (str): applies selected activation from supported_act_functions.
          See activation_functions.py for more info about supported activations.
          Currently ReLU ('relu'), Swish ('swish'), Hardswish ('hswish'), Identity
          ('identity') are supported.
      use_bn (bool): if true, use batchnorm.
      norm_eps (float): epsilon for batchnorm.
      norm_momentum (float): momentum for batchnorm.
class_docstr_tok: ["Implements","Conv3d","+","Bn","+","Activation","for","pointwise","layers",".","The","conv","layer","has","fixed","kernel_size","=","(","1,1,1",")",",","groups","=","1",",","padding","=","0",",","stride","=","1",",","dilation","=","1",".","Input","|","\u2193","conv3d","(","1x1x1",")","\u2193","BatchNorm","(","optional",")","\u2193","Activation","Conv3dPwBnAct","is","in","original","form","(","for","training",")","once","instantiated",".","User","can","call","convert","(",")","method","to","convert","it","into","deployable","form","for","deployment",".","convert_flag","variable","is","to","record","whether","the","Conv3dPwBnAct","instance","has","been","converted",";","Conv3dPwBnAct","is","in","original","form","if","convert_flag","is","false",",","while","it","is","in","deployable","form","if","convert_flag","is","true",".","Current","implementation","of","this","layer","in","QNNPACK","is","very","efficient",".","Args",":","in_channels","(","int",")",":","number","of","input","channels","for","conv3d","1x1x1",".","out_channels","(","int",")",":","number","of","output","channels","for","conv3d","1x1x1",".","bias","(","bool",")",":","if","true",",","use","bias","for","conv",".","activation","(","str",")",":","applies","selected","activation","from","supported_act_functions",".","See","activation_functions.py","for","more","info","about","supported","activations",".","Currently","ReLU","(","'relu","'",")",",","Swish","(","'swish","'",")",",","Hardswish","(","'hswish","'",")",",","Identity","(","'identity","'",")","are","supported",".","use_bn","(","bool",")",":","if","true",",","use","batchnorm",".","norm_eps","(","float",")",":","epsilon","for","batchnorm",".","norm_momentum","(","float",")",":","momentum","for","batchnorm","."]
docstr: Converts the block into efficient form.
  For fp32 operation, or quantized but with older version of QNNPACK w/o native int8
  Conv3d support, this function converts Conv3d into equivalent Conv2d for Pytorch
  Mobile deployment.
  The Conv3d -> Conv2d conversion is done by first fuse conv3d with bn,
  convert conv3d into equivalent conv2d, and optionally fuse conv2d with relu.
  After conversion, the forwarding of this module becomes:
  Input (5d tensor) --> reshape (4d tensor) --> conv2d (4d tensor)
      --> reshape (5d tensor) --> output (5d tensor)
  
  For quantized operation on new version of QNNPACK with native int8 Conv3d, this
  function will only apply operator fusion.
  Args:
      input_blob_size (tuple): blob size at the input of Conv3dPwBnAct instance.
      convert_for_quantize (bool): whether this module is intended to be quantized.
      native_conv3d_op_qnnpack (bool): whether the QNNPACK version has native int8
          Conv3d.
      kwargs (any): any extra keyword arguments from upstream unused by convert().
docstr_tok: ["Converts","the","block","into","efficient","form",".","For","fp32","operation",",","or","quantized","but","with","older","version","of","QNNPACK","w\/o","native","int8","Conv3d","support",",","this","function","converts","Conv3d","into","equivalent","Conv2d","for","Pytorch","Mobile","deployment",".","The","Conv3d","-",">","Conv2d","conversion","is","done","by","first","fuse","conv3d","with","bn",",","convert","conv3d","into","equivalent","conv2d",",","and","optionally","fuse","conv2d","with","relu",".","After","conversion",",","the","forwarding","of","this","module","becomes",":","Input","(","5d","tensor",")","--",">","reshape","(","4d","tensor",")","--",">","conv2d","(","4d","tensor",")","--",">","reshape","(","5d","tensor",")","--",">","output","(","5d","tensor",")","For","quantized","operation","on","new","version","of","QNNPACK","with","native","int8","Conv3d",",","this","function","will","only","apply","operator","fusion",".","Args",":","input_blob_size","(","tuple",")",":","blob","size","at","the","input","of","Conv3dPwBnAct","instance",".","convert_for_quantize","(","bool",")",":","whether","this","module","is","intended","to","be","quantized",".","native_conv3d_op_qnnpack","(","bool",")",":","whether","the","QNNPACK","version","has","native","int8","Conv3d",".","kwargs","(","any",")",":","any","extra","keyword","arguments","from","upstream","unused","by","convert","(",")","."]
code: def convert(
      self,
      input_blob_size: Tuple,
      convert_for_quantize: bool = False,
      native_conv3d_op_qnnpack: bool = False,
      **kwargs,
  ):
      """
      Converts the block into efficient form.
      For fp32 operation, or quantized but with older version of QNNPACK w/o native int8
      Conv3d support, this function converts Conv3d into equivalent Conv2d for Pytorch
      Mobile deployment.
      The Conv3d -> Conv2d conversion is done by first fuse conv3d with bn,
      convert conv3d into equivalent conv2d, and optionally fuse conv2d with relu.
      After conversion, the forwarding of this module becomes:
      Input (5d tensor) --> reshape (4d tensor) --> conv2d (4d tensor)
          --> reshape (5d tensor) --> output (5d tensor)
  
      For quantized operation on new version of QNNPACK with native int8 Conv3d, this
      function will only apply operator fusion.
      Args:
          input_blob_size (tuple): blob size at the input of Conv3dPwBnAct instance.
          convert_for_quantize (bool): whether this module is intended to be quantized.
          native_conv3d_op_qnnpack (bool): whether the QNNPACK version has native int8
              Conv3d.
          kwargs (any): any extra keyword arguments from upstream unused by convert().
      """
      assert (
          self.convert_flag is False
      ), "Conv3dPwBnAct: already converted, cannot be converted again"
      self.kernel.eval()
      # First fuse conv and bn if bn exists.
      if hasattr(self.kernel, "bn"):
          self.kernel = fuse_modules(self.kernel, ["conv", "bn"])
      # If user intends to quantize the module and their QNNPACK comes with native int8 Conv3d,
      # then we just need to do fusion.
      if convert_for_quantize and native_conv3d_op_qnnpack:
          if self.act == "relu":
              self.kernel = fuse_modules(
                  self.kernel, ["conv", "act.act"]
              )
          # Set new kernel in eval mode again
          self.kernel.eval()
      # Else, for fp32 operation or for int8 but with older version of QNNPACK w/o native int8 Conv3d,
      # we need to unfold Conv3d into Conv2ds.
      else:
          batch_size = input_blob_size[0]
          input_THW_tuple = input_blob_size[2:]
          self._input_tensor_reshape_size = (
              batch_size,
              self._in_channels,  # C
              input_THW_tuple[0] * input_THW_tuple[1],  # T*H
              input_THW_tuple[2],  # W
          )
          self._output_tensor_size = (
              batch_size,
              self._out_channels,  # C
              input_THW_tuple[0],  # T
              input_THW_tuple[1],  # H
              input_THW_tuple[2],  # W
          )
          conv2d_eq = nn.Conv2d(
              self._in_channels,
              self._out_channels,
              kernel_size=1,
              bias=(self.kernel.conv.bias is not None),
          )
          conv_state_dict = self.kernel.conv.state_dict()
          conv_state_dict["weight"] = conv_state_dict["weight"].squeeze(
              2
          )
          conv2d_eq.load_state_dict(conv_state_dict)
          self.kernel.conv = conv2d_eq
          # Convert activatiopn function
          self.kernel.act.convert(input_blob_size, **kwargs)
          # Fuse act with conv after conv3d -> conv2d if act is relu
          if self.act == "relu":
              self.kernel = fuse_modules(
                  self.kernel, ["conv", "act.act"]
              )
          # Insert reshape layers before/after conv2d
          self.kernel = nn.Sequential(
              _Reshape(self._input_tensor_reshape_size),
              self.kernel,
              _Reshape(self._output_tensor_size),
          )
          # Set new kernel in eval mode again
          self.kernel.eval()
      self.convert_flag = True
  
imports: import logging
  from collections import OrderedDict
  from typing import Tuple
  import torch
  import torch.nn
  from pytorchvideo.accelerator.efficient_blocks.efficient_block_base import EfficientBlockBase
  from .activation_functions import supported_act_functions
  from .conv_helper import _Conv3dTemporalKernel1Decomposed, _Conv3dTemporalKernel3Decomposed, _Conv3dTemporalKernel5Decomposed, _Reshape
label_desc: Use image node_id 2 for calling the Conv3dPwBnAct obj's underlying member method code with example usage: obj.convert(input_blob_size, convert_for_quantize, native_conv3d_op_qnnpack) without return types