content: # flake8: noqa
  import logging
  import math
  import operator
  import warnings
  from typing import Dict, Optional, Sequence, Tuple, Union, cast
  
  import numpy as np
  
  # @manual=//deeplearning/trt/python:py_tensorrt
  import tensorrt as trt
  import torch
  from torch.fx.immutable_collections import immutable_list
  from torch.fx.node import Argument, Target
  from torch_tensorrt.fx.converters.impl import activation, convolution
  from torch_tensorrt.fx.passes.lower_basic_pass import (
      trt_transposed_linear,
      trt_transposed_matmul,
  )
  from torch_tensorrt.fx.tracer.acc_tracer.acc_ops import contiguous
  
  from ..converter_registry import tensorrt_converter
  from ..tracer.acc_tracer import acc_ops
  from ..types import *  # noqa: F403
  from ..utils import Frameworks, get_dynamic_dims, unified_dtype_converter
  from .converter_utils import *  # noqa: F403
  
  _LOGGER: logging.Logger = logging.getLogger(__name__)
  
  
  @tensorrt_converter(trt_transposed_matmul)
  def trt_transposed_matmul_converter(network, target, args, kwargs, name):
      lhs, rhs, lhs_transposed, rhs_transposed = args
  
      if isinstance(lhs, torch.nn.Parameter):
          lhs = get_trt_tensor(network, lhs, f"{name}_lhs")
      if isinstance(rhs, torch.nn.Parameter):
          rhs = get_trt_tensor(network, rhs, f"{name}_rhs")
  
      lhs, rhs = broadcast(
          network,
          lhs,
          rhs,
          f"{lhs.name}_broadcast",
          f"{rhs.name}_broadcast",
      )
      layer = network.add_matrix_multiply(
          lhs,
          trt.MatrixOperation.TRANSPOSE if lhs_transposed else trt.MatrixOperation.NONE,
          rhs,
          trt.MatrixOperation.TRANSPOSE if rhs_transposed else trt.MatrixOperation.NONE,
      )
      set_layer_name(layer, target, name)
      return layer.get_output(0)
  
  
  @tensorrt_converter(trt_transposed_linear)
  def trt_transposed_linear_converter(network, target, args, kwargs, name):
      input, weight, bias = args
  
      weight = get_trt_tensor(network, weight.t(), f"{name}_weight")
      bias = get_trt_tensor(network, bias.reshape(1, -1), f"{name}_bias")
  
      input, weight = broadcast(
          network,
          input,
          weight,
          f"{input.name}_broadcast",
          f"{weight.name}_broadcast",
      )
      layer = network.add_matrix_multiply(
          input,
          trt.MatrixOperation.TRANSPOSE,
          weight,
          trt.MatrixOperation.NONE,
      )
      set_layer_name(layer, target, f"{name}_mm")
      return add_binary_elementwise_layer(
          network,
          layer.get_output(0),
          bias,
          trt.ElementWiseOperation.SUM,
          target,
          f"{name}_add",
      )
  
  
  @tensorrt_converter(acc_ops.conv1d)
  def acc_ops_conv1d(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return convolution.convNd(
          network,
          target,
          source_ir=SourceIR.ACC,
          name=name,
          is_conv1d=True,
          input_val=kwargs["input"],
          weight=kwargs["weight"],
          bias=kwargs["bias"],
          stride=kwargs["stride"],
          padding=kwargs["padding"],
          dilation=kwargs["dilation"],
          groups=kwargs["groups"],
      )
  
  
  @tensorrt_converter(acc_ops.conv3d)
  @tensorrt_converter(acc_ops.conv2d)
  def acc_ops_convnd(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return convolution.convNd(
          network,
          target,
          source_ir=SourceIR.ACC,
          name=name,
          is_conv1d=False,
          input_val=kwargs["input"],
          weight=kwargs["weight"],
          bias=kwargs["bias"],
          stride=kwargs["stride"],
          padding=kwargs["padding"],
          dilation=kwargs["dilation"],
          groups=kwargs["groups"],
      )
  
  
  @tensorrt_converter(acc_ops.conv_transpose2d)
  @tensorrt_converter(acc_ops.conv_transpose3d)
  def acc_ops_conv_transposend(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"Transpose conv received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if has_dynamic_shape(input_val.shape):
          assert (
              input_val.shape[1] != -1
          ), "Channel dim can't be dynamic for transpose convolution."
  
      # for now we'll assume bias is constant Tensor or None,
      # and bias being ITensor is not supported in TensorRT api
      # right now
      if kwargs["bias"] is not None and not isinstance(kwargs["bias"], torch.Tensor):
          raise RuntimeError(
              f"ConvTranspose {name} has bias of type {type(kwargs['bias'])}, Expect Optional[Tensor]"
          )
      bias = to_numpy(kwargs["bias"])  # type: ignore[arg-type]
  
      if network.has_explicit_precision or isinstance(kwargs["weight"], TRTTensor):
          weight = get_trt_tensor(network, kwargs["weight"], f"{name}_weight")
          weight_shape = tuple(kwargs["weight"].shape)  # type: ignore[union-attr]
          # will need to use uninitialized weight and set it later to support
          # ITensor weights
          dummy_weight = trt.Weights()
  
          # nn.ConvTranspose2d/3d weight size is (in_channels, out_channels/groups, kernel_0, kernel_1, [kernel_2])
          layer = network.add_deconvolution_nd(
              input=input_val,
              num_output_maps=weight.shape[1] * kwargs["groups"],
              kernel_shape=weight.shape[2:],
              kernel=dummy_weight,
              bias=bias,
          )
  
          layer.set_input(1, weight)
      else:
          if not isinstance(kwargs["weight"], torch.Tensor):
              raise RuntimeError(
                  f"conv {name} has weight of type {type(kwargs['weight'])}, Expect Optional[Tensor]"
              )
          weight = to_numpy(kwargs["weight"])
          # nn.ConvTranspose2d/3d weight size is (in_channels, out_channels/groups, kernel_0, kernel_1, [kernel_2])
          layer = network.add_deconvolution_nd(
              input=input_val,
              num_output_maps=weight.shape[1] * kwargs["groups"],
              kernel_shape=weight.shape[2:],
              kernel=weight,
              bias=bias,
          )
  
      set_layer_name(layer, target, name)
      layer.stride_nd = kwargs["stride"]
      layer.padding_nd = kwargs["padding"]
      layer.dilation_nd = kwargs["dilation"]
      if kwargs["groups"] is not None:
          layer.num_groups = kwargs["groups"]
  
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.pad, enabled=trt.__version__ < "8.2")
  def acc_ops_pad_with_padding_layer(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      pad = cast(Sequence[int], kwargs["pad"])
      mode = kwargs["mode"]
      value = kwargs["value"] if kwargs["value"] is not None else 0
      rank = len(input_val.shape)  # type: ignore[union-attr]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"pad received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if mode != "constant":
          raise RuntimeError(
              f"Currently we only support constant mode for pad, got {mode}."
          )
  
      if len(pad) / 2 > rank:
          raise RuntimeError(
              f"Trying to pad last {len(pad) / 2} dimension but the input only has {rank} dimension."
          )
  
      if value != 0:
          raise RuntimeError(
              f"Currently we only support padding value of 0, got {value}."
          )
  
      if len(pad) > 4:
          raise RuntimeError("Currently we only support padding last two dimensions.")
  
      pre_padding = tuple(pad[len(pad) - i - 2] for i in range(0, len(pad), 2))
      post_padding = tuple(pad[len(pad) - i - 1] for i in range(0, len(pad), 2))
  
      layer = network.add_padding(
          input_val,
          pre_padding if len(pre_padding) == 2 else (0,) + pre_padding,
          post_padding if len(post_padding) == 2 else (0,) + post_padding,
      )
      set_layer_name(layer, target, name)
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.pad, enabled=trt.__version__ >= "8.2")
  def acc_ops_pad_with_slice_layer(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      pad = cast(Sequence[int], kwargs["pad"])
      mode = kwargs["mode"]
      value = kwargs["value"] if kwargs["value"] is not None else 0
      rank = len(input_val.shape)  # type: ignore[union-attr]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"pad received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if mode != "constant":
          raise RuntimeError(
              f"Currently we only support constant mode for pad, got {mode}."
          )
  
      if len(pad) / 2 > rank:
          raise RuntimeError(
              f"Trying to pad last {len(pad) / 2} dimension but the input only has {rank} dimension."
          )
  
      # cast value to TRTensor
      dt = unified_dtype_converter(input_val.dtype, Frameworks.TORCH)
      value = 0 if value == None else value
      value_const = get_trt_tensor(
          network, torch.tensor([value], dtype=dt), f"{name}_value"
      )
  
      input_shape = input_val.shape
      prefix_len = len(input_shape) - len(pad) // 2
      start = tuple(
          -pad[-(i - prefix_len) * 2 - 2] if i >= prefix_len else 0
          for i in range(0, len(input_shape))
      )
  
      shape = tuple(
          input_shape[i]
          + (
              pad[-(i - prefix_len) * 2 - 1] + pad[-(i - prefix_len) * 2 - 2]
              if i >= prefix_len
              else 0
          )
          for i in range(0, len(input_shape))
      )
      stride = tuple([1] * len(shape))
  
      layer = network.add_slice(
          input_val,
          start,
          shape,
          stride,
      )
  
      layer.set_input(4, value_const)
      layer.mode = trt.SampleMode.FILL
      set_layer_name(layer, target, name)
  
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.flatten)
  def acc_ops_flatten(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"flatten received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      num_dims = len(input_val.shape) + (1 if network.has_implicit_batch_dimension else 0)
      start_dim = get_positive_dim(
          cast(int, kwargs["start_dim"] if "start_dim" in kwargs else 0), num_dims
      )
      end_dim = get_positive_dim(
          cast(int, kwargs["end_dim"] if "end_dim" in kwargs else -1), num_dims
      )
  
      if network.has_implicit_batch_dimension:
          assert start_dim != 0, "Can't flatten batch dimension when it's implicit."
          start_dim -= 1
          end_dim -= 1
  
      layer = network.add_shuffle(input_val)
      set_layer_name(layer, target, name)
  
      # If there're dynamic shapes then we need to use shape layers
      # to figure out the final shape after flatten. We first slice
      # the input shape to three parts:
      #   1. dimensions before start_dim
      #   2. dimensions between start_dim and end_dim
      #   3. dimensions after end_dim
      # Part 1 and 3 might not exist if start_dim is 0 or end_dim is
      # last dim. Then we do a reduced multiplication over part 2 to
      # get flattened dim. Finally, we concatenate the three parts to
      # get the final shape.
      if has_dynamic_shape(input_val.shape):
          input_shape_layer = network.add_shape(input_val)
          input_shape_layer.name = f"{name}_orig_shape"
  
          final_shapes = []
  
          # Shapes before start_dim
          if start_dim > 0:
              prefix_shape_layer = network.add_slice(
                  input_shape_layer.get_output(0),
                  start=(0,),
                  shape=(start_dim,),
                  stride=(1,),
              )
              prefix_shape_layer.name = f"{name}_pre_shape"
              final_shapes.append(prefix_shape_layer.get_output(0))
  
          flatten_shape_layer = network.add_slice(
              input_shape_layer.get_output(0),
              start=(start_dim,),
              shape=(end_dim - start_dim + 1,),
              stride=(1,),
          )
          flatten_shape_layer.name = f"{name}_need_flatten"
          flatten_shape_layer = network.add_reduce(
              flatten_shape_layer.get_output(0),
              trt.ReduceOperation.PROD,
              axes=get_axes_for_reduce_op(0, False),
              keep_dims=True,
          )
          flatten_shape_layer.name = f"{name}_flatten_dim"
          final_shapes.append(flatten_shape_layer.get_output(0))
  
          # Shapes after start_dim
          if end_dim < len(input_val.shape) - 1:
              suffix_shape_layer = network.add_slice(
                  input_shape_layer.get_output(0),
                  start=(end_dim + 1,),
                  shape=(len(input_val.shape) - end_dim - 1,),
                  stride=(1,),
              )
              suffix_shape_layer.name = f"{name}_suffix_shape"
              final_shapes.append(suffix_shape_layer.get_output(0))
  
          final_shape_layer = network.add_concatenation(final_shapes)
          final_shape_layer.axis = 0
          final_shape_layer.name = f"{name}_final_shape"
          layer.set_input(1, final_shape_layer.get_output(0))
      else:
          final_shape = []
          flatten_dim = 1
          for i, s in enumerate(input_val.shape):
              if i >= start_dim and i <= end_dim:
                  flatten_dim *= s
              elif i == end_dim + 1:
                  final_shape.append(flatten_dim)
                  final_shape.append(s)
              else:
                  final_shape.append(s)
          if end_dim == len(input_val.shape) - 1:
              final_shape.append(flatten_dim)
  
          layer.reshape_dims = tuple(final_shape)
  
      return layer.get_output(0)
  
  
  # For implicit batch dim mode, we use this to represent batch dim if we
  # ever trying to retrieve it via size() and we hope it will fail hard if
  # it's used somewhere else.
  IMPLICIT_BATCH_DIM = -999
  
  
  @tensorrt_converter(acc_ops.size)
  def acc_ops_size(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_t = kwargs["input"]
      if type(input_t) == torch.nn.Parameter or type(input_t) == torch.Tensor:
          if (
              not has_dynamic_shape(input_t.shape)
              and network.has_implicit_batch_dimension
          ):
              return torch.Size((IMPLICIT_BATCH_DIM,) + tuple(input_t.shape))
          return input_t.shape
  
      # input_val = get_trt_tensor(network, input_t, f"{name}_input_t")
      input_val = input_t
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"size received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if not has_dynamic_shape(input_val.shape):
          if network.has_implicit_batch_dimension:
              return torch.Size((IMPLICIT_BATCH_DIM,) + tuple(input_val.shape))
          return torch.Size(input_val.shape)
  
      layer = network.add_shape(input_val)
      set_layer_name(layer, target, name)
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.numel)
  def acc_ops_numel(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"size received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if has_dynamic_shape(input_val.shape):
          raise RuntimeError(f"numel does not support dynamic shapes.")
  
      numel = np.prod(input_val.shape)
      layer = network.add_constant((1,), trt.Weights(np.array(numel, dtype=np.float32)))
      set_layer_name(layer, target, name)
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.batch_norm)
  def acc_ops_batch_norm(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"BatchNorm2d received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      if has_dynamic_shape(input_val.shape):
          assert input_val.shape[1] != -1, "Channel dim can't be dynamic for batch norm."
  
      scale = cast(
          torch.Tensor, to_numpy(cast(torch.Tensor, kwargs["weight"]))
      ) / np.sqrt(
          cast(torch.Tensor, to_numpy(cast(torch.Tensor, kwargs["running_var"])))
          + cast(float, kwargs["eps"])
      )
  
      bias = (
          to_numpy(cast(torch.Tensor, kwargs["bias"]))
          - to_numpy(cast(torch.Tensor, kwargs["running_mean"])) * scale
      )
      power = np.ones_like(scale)
  
      # For BatchNorm1d, reshape 1d to 2d
      output_shape = input_val.shape
      if not network.has_implicit_batch_dimension and len(input_val.shape) < 4:
          assert (
              len(get_dynamic_dims(input_val.shape)) <= 1
          ), "BatchNorm1D with more than one dynamic dims is not currently supported."
          reshape_layer = network.add_shuffle(input_val)
          if len(input_val.shape) == 2:
              reshape_layer.reshape_dims = (input_val.shape[0], input_val.shape[1], 1, 1)
          else:  # len(input_val.shape) == 3
              reshape_layer.reshape_dims = (
                  input_val.shape[0],
                  input_val.shape[1],
                  input_val.shape[2],
                  1,
              )
          set_layer_name(reshape_layer, target, f"{name}_reshape_2d")
          input_val = reshape_layer.get_output(0)
      layer = network.add_scale(input_val, trt.ScaleMode.CHANNEL, bias, scale, power)
      set_layer_name(layer, target, name)
  
      # For BatchNorm1d, reshape output back to 1d
      if not network.has_implicit_batch_dimension and len(output_shape) < 4:
          reshape_output_layer = network.add_shuffle(layer.get_output(0))
          reshape_output_layer.reshape_dims = tuple(output_shape)
          set_layer_name(reshape_output_layer, target, f"{name}_reshape_1d")
          layer = reshape_output_layer
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.layer_norm)
  def acc_ops_layer_norm(network, target, args, kwargs, name):
      input_val = kwargs["input"]
  
      if not isinstance(input_val, trt.tensorrt.ITensor):
          raise RuntimeError(
              f"LayerNorm received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      gamma = kwargs["weight"].detach().cpu().float().numpy()
      gamma_field = trt.PluginField("gamma", gamma, trt.PluginFieldType.FLOAT32)
      beta = kwargs["bias"].detach().cpu().float().numpy()
      beta_field = trt.PluginField("beta", beta, trt.PluginFieldType.FLOAT32)
      eps_field = trt.PluginField(
          "eps", np.array([kwargs["eps"]], dtype=np.float32), trt.PluginFieldType.FLOAT32
      )
      normalized_shape = kwargs["normalized_shape"]
      try:
          normalized_shape = np.array(normalized_shape, dtype=np.int32)
      except TypeError:
          _LOGGER.error(
              f"Unable to convert normalized_shape with value {normalized_shape} to a field, fall back to []"
          )
          normalized_shape = np.array([], dtype=np.int32)
  
      normalized_shape_filed = trt.PluginField(
          "normalized_shape", normalized_shape, trt.PluginFieldType.INT32
      )
      field_collection = trt.PluginFieldCollection(
          [gamma_field, beta_field, eps_field, normalized_shape_filed]
      )
  
      try:
          if network.has_implicit_batch_dimension:
              plugin = get_trt_plugin("layer_norm", field_collection, "1", "fx2trt")
          else:
              plugin = get_trt_plugin("LayerNormDynamic", field_collection, "1", "fx2trt")
      except AssertionError:
          _LOGGER.error(
              "Unable to find layer norm plugin, fall back to TensorRT implementation."
          )
          return layer_norm(network, target, args, kwargs, name)
      layer = network.add_plugin_v2([input_val], plugin)
      layer.name = name
      return layer.get_output(0)
  
  
  def layer_norm(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"LayerNorm received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      shape = kwargs["weight"].shape  # type: ignore[union-attr]
      broadcasted_shape = (1,) * (len(input_val.shape) - len(shape)) + shape
      gamma = to_numpy(kwargs["weight"].reshape(*shape))  # type: ignore[union-attr]
      beta = to_numpy(kwargs["bias"].reshape(*shape))  # type: ignore[union-attr]
      eps = kwargs["eps"]
  
      axes = 0
      for d in range(len(shape)):
          axes |= 1 << (len(input_val.shape) - d - 1)
  
      # E[x]
      mean_expected_layer = network.add_reduce(
          input_val, trt.ReduceOperation.AVG, axes, keep_dims=True
      )
      set_layer_name(mean_expected_layer, target, f"{name}_mean_expected")
  
      # X-E[x]
      sub_trt = add_binary_elementwise_layer(
          network,
          input_val,
          mean_expected_layer.get_output(0),
          trt.ElementWiseOperation.SUB,
          target,
          f"{name}_sub",
      )
      # Variance = mean(pow(x_sub_mean,2))
      pow_tensor = network.add_constant(
          (1,) * len(input_val.shape),
          trt.Weights(np.ascontiguousarray([2.0], dtype=np.float32)),
      )
      pow_tensor.name = f"{name}_power"
      pow_var = add_binary_elementwise_layer(
          network,
          sub_trt,
          pow_tensor.get_output(0),
          trt.ElementWiseOperation.POW,
          target,
          f"{name}_pow_var",
      )
      mean_trt_layer = network.add_reduce(
          pow_var, trt.ReduceOperation.AVG, axes, keep_dims=True
      )
      set_layer_name(mean_trt_layer, target, f"{name}_mean")
      # Variance + eps
      eps_tensor = network.add_constant(
          (1,) * len(input_val.shape),
          trt.Weights(np.ascontiguousarray([eps], dtype=np.float32)),
      )
      eps_tensor.name = f"{name}_eps"
      add_trt = add_binary_elementwise_layer(
          network,
          mean_trt_layer.get_output(0),
          eps_tensor.get_output(0),
          trt.ElementWiseOperation.SUM,
          target,
          f"{name}_add",
      )
      # SQRT((Var + eps))
      sqrt_trt = add_unary_layer(
          network, add_trt, trt.UnaryOperation.SQRT, target, f"{name}_sqrt"
      )
      # (x - E[x]) / sqrt((var + eps))
      div_trt = add_binary_elementwise_layer(
          network,
          sub_trt,
          sqrt_trt,
          trt.ElementWiseOperation.DIV,
          target,
          f"{name}_div_trt",
      )
  
      assert gamma is not None
      gamma_tensor = network.add_constant(gamma.shape, trt.Weights(np.ascontiguousarray(gamma)))  # type: ignore[attr-defined]
      gamma_tensor.name = f"{name}_gamma"
      assert beta is not None
      beta_tensor = network.add_constant(gamma.shape, trt.Weights(np.ascontiguousarray(beta)))  # type: ignore[attr-defined]
      beta_tensor.name = f"{name}_beta"
      # y * gamma + beta
      scale_layer = add_binary_elementwise_layer(
          network,
          div_trt,
          gamma_tensor.get_output(0),
          trt.ElementWiseOperation.PROD,
          target,
          f"{name}_scale",
      )
      return add_binary_elementwise_layer(
          network,
          scale_layer,
          beta_tensor.get_output(0),
          trt.ElementWiseOperation.SUM,
          target,
          name,
      )
  
  
  @tensorrt_converter(acc_ops.softmax)
  def acc_ops_softmax(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      input_ranks = len(input_val.shape) + (1 if network.has_implicit_batch_dimension else 0)  # type: ignore[union-attr]
  
      if not isinstance(input_val, TRTTensor):
          raise RuntimeError(
              f"softmax received input {input_val} that is not part "
              "of the TensorRT region!"
          )
  
      # Used to get dim when dim is None. Copied from PyTorch softmax implementation.
      def get_softmax_dim(ndim: int) -> int:
          if ndim == 0 or ndim == 1 or ndim == 3:
              ret = 0
          else:
              ret = 1
          return ret
  
      if kwargs["dim"] is None:
          dim = get_softmax_dim(input_ranks)
      else:
          dim = cast(int, kwargs["dim"])
  
      dim = get_positive_dim(dim, input_ranks)
      if network.has_implicit_batch_dimension:
          assert dim != 0, "Can't apply softmax on batch dimension when it's implicit."
          dim -= 1
  
      layer = network.add_softmax(input_val)
      layer.axes = 1 << dim
      set_layer_name(layer, target, name)
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.tile)
  def acc_ops_tile(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_t = kwargs["input"]
      input_val = get_trt_tensor(network, input_t, f"{name}_input")
  
      dims = tuple(cast(Sequence[int], kwargs["dims"]))
      n_input_dims = len(input_val.shape) + (
          1 if network.has_implicit_batch_dimension else 0
      )
  
      if len(dims) > n_input_dims:
          assert not network.has_implicit_batch_dimension
          layer = network.add_shuffle(input_val)
          layer.name = f"{name}_reshape"
          num_preceding_ones = len(dims) - n_input_dims
  
          if len(get_dynamic_dims(input_val.shape)) > 1:
              input_shape_layer = network.add_shape(input_val)
              input_shape_layer.name = f"{name}_input_shape"
              preceding_ones = network.add_constant(
                  (num_preceding_ones,),
                  np.ascontiguousarray([1] * num_preceding_ones, np.int32),
              ).get_output(0)
              reshape_layer = network.add_concatenation(
                  [preceding_ones, input_shape_layer.get_output(0)]
              )
              reshape_layer.axis = 0
              reshape_layer.name = f"{name}_reshape_dims"
              layer.set_input(1, reshape_layer.get_output(0))
          else:
              layer.reshape_dims = (1,) * (len(dims) - n_input_dims) + tuple(
                  input_val.shape
              )
          input_val = layer.get_output(0)
      else:
          dims = (1,) * (n_input_dims - len(dims)) + dims
  
      if network.has_implicit_batch_dimension:
          assert dims[0] == 1, "Can't tile the batch dim when it's implicit."
          dims = dims[1:]
      starts = [0] * len(dims)
      shapes = []
      if all(isinstance(d, int) for d in dims):
          shapes = [i * j for i, j in zip(input_val.shape, dims)]  # type: ignore[union-attr]
      else:
          shape = []
          for i, (s, d) in enumerate(zip(input_val.shape, dims)):
              if isinstance(d, TRTTensor) and len(d.shape) == 0:
                  d = prepend_ones(network, d, f"{name}_{i}", 1)
              else:
                  d = get_trt_tensor(network, d, f"{name}_{i}")
              shape.append(d)
              mul = add_binary_elementwise_layer(
                  network,
                  s,
                  d,
                  trt.ElementWiseOperation.PROD,
                  target,
                  f"{name}_mul_{i}",
              )
              shapes.append(mul)
          dims = shape
      # If there's dynmaic dim then there would be negative dims in shapes which is not allowed.
      # Here we build a dummy shapes array.
      if has_dynamic_shape(input_val.shape):  # type: ignore[union-attr]
          shapes = [1] * len(dims)
      strides = [1] * len(dims)
      layer = network.add_slice(input_val, starts, shapes, strides)
      layer.mode = trt.SampleMode.WRAP
      set_layer_name(layer, target, name)
  
      if has_dynamic_shape(input_val.shape):  # type: ignore[union-attr]
          starts_tensor = network.add_constant(
              (len(dims),), np.ascontiguousarray([0] * len(dims), np.int32)
          ).get_output(0)
          if all(isinstance(d, int) for d in dims):
              dims_tensor = network.add_constant(
                  (len(dims),), np.ascontiguousarray(dims, np.int32)
              ).get_output(0)
          else:
              assert all(isinstance(d, TRTTensor) for d in dims)
              concat_dims_layer = network.add_concatenation(inputs=dims)
              concat_dims_layer.axis = 0
              concat_dims_layer.name = f"{name}_tile_dim"
              dims_tensor = concat_dims_layer.get_output(0)
          input_shape_layer = network.add_shape(input_val)
          input_shape_layer.name = f"{name}_slice_input_shape"
          slice_shapes_tensor = add_binary_elementwise_layer(
              network,
              input_shape_layer.get_output(0),
              dims_tensor,
              trt.ElementWiseOperation.PROD,
              target,
              f"{name}_slice_shapes",
          )
          layer.set_input(1, starts_tensor)
          layer.set_input(2, slice_shapes_tensor)
  
      return layer.get_output(0)
  
  
  @tensorrt_converter(acc_ops.sign)
  def acc_ops_sign(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
  
      if trt.__version__ >= "8.2" and not network.has_implicit_batch_dimension:
          input_val = kwargs["input"]
          operation_type = trt.UnaryOperation.SIGN
          return add_unary_layer(network, input_val, operation_type, target, name)
  
      return sign(network, input_val, target, name)
  
  
  @tensorrt_converter(acc_ops.relu)
  def acc_ops_relu(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return activation.relu(
          network,
          target,
          SourceIR.ACC,
          name,
          kwargs["input"],
      )
  
  
  @tensorrt_converter(acc_ops.leaky_relu)
  def acc_ops_leaky_relu(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return activation.leaky_relu(
          network, target, SourceIR.ACC, name, kwargs["input"], kwargs["negative_slope"]
      )
  
  
  @tensorrt_converter(acc_ops.elu)
  def acc_ops_elu(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return activation.elu(
          network,
          target,
          SourceIR.ACC,
          name,
          kwargs["input"],
          kwargs["alpha"],
      )
  
  
  @tensorrt_converter(acc_ops.selu)
  def acc_ops_selu(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      return activation.selu(
          network,
          target,
          SourceIR.ACC,
          name,
          kwargs["input"],
      )
  
  
  @tensorrt_converter(acc_ops.softsign)
  def acc_ops_softsign(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      operation_type = trt.ActivationType.SOFTSIGN
      return activation.convert_activation(
          network,
          target,
          SourceIR.ACC,
          name,
          operation_type,
          input_val,
      )
  
  
  @tensorrt_converter(acc_ops.sin)
  def acc_ops_sin(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      operation_type = trt.UnaryOperation.SIN
      return add_unary_layer(network, input_val, operation_type, target, name)
  
  
  @tensorrt_converter(acc_ops.cos)
  def acc_ops_cos(
      network: TRTNetwork,
      target: Target,
      args: Tuple[Argument, ...],
      kwargs: Dict[str, Argument],
      name: str,
  ) -> Union[TRTTensor, Sequence[TRTTensor]]:
      input_val = kwargs["input"]
      operation_type = trt.UnaryOperation.COS
      return add_unary_layer(network, input_val, operation_type, target, name)
  
  
  @tensorrt_converter(acc_ops.tan)
  def acc_ops_tan(
      network: TRTNetwork,
  