code: def _ConvolutionLayerParams(op, inexpr, etab):
      """Convolution layer params."""
      if op.isDeconvolution:
          weights = etab.new_const(
              np.array(list(op.weights.floatValue)).reshape(
                  tuple(
                      [op.kernelChannels, op.outputChannels]
                      + list(op.kernelSize)
                  )
              )
          )
      else:
          weights = etab.new_const(
              np.array(list(op.weights.floatValue)).reshape(
                  tuple(
                      [op.outputChannels, op.kernelChannels]
                      + list(op.kernelSize)
                  )
              )
          )
      dilation = list(op.dilationFactor)
      if not dilation:
          dilation = [1, 1]
      N, C, H, W = _infer_shape(inexpr)
      params = {
          "channels": op.outputChannels,
          "kernel_size": list(op.kernelSize),
          "strides": list(op.stride),
          "dilation": dilation,
          "groups": op.nGroups,
      }
  
      if op.WhichOneof("ConvolutionPaddingType") == "valid":
          valid = op.valid
          if valid.paddingAmounts.borderAmounts:
              assert len(valid.paddingAmounts.borderAmounts) == 2
              pad_t = valid.paddingAmounts.borderAmounts[
                  0
              ].startEdgeSize
              pad_l = valid.paddingAmounts.borderAmounts[
                  1
              ].startEdgeSize
              pad_b = valid.paddingAmounts.borderAmounts[0].endEdgeSize
              pad_r = valid.paddingAmounts.borderAmounts[1].endEdgeSize
              if not all(v == 0 for v in (pad_t, pad_l, pad_b, pad_r)):
                  params["padding"] = (pad_t, pad_l, pad_b, pad_r)
      elif op.WhichOneof("ConvolutionPaddingType") == "same":
          assert op.same.asymmetryMode == 0, (
              "Only support BOTTOM_RIGHT_HEAVY mode, "
              "which is used by tf/caffe and so on"
          )
          kernel = params["kernel_size"]
          strides = params["strides"]
          pad_t, pad_b = get_pad_value(H, kernel[0], strides[0])
          pad_l, pad_r = get_pad_value(W, kernel[1], strides[1])
          params["padding"] = (pad_t, pad_l, pad_b, pad_r)
      else:
          raise NotImplementedError(
              "Valid/Same convolution padding implemented"
          )
  
      if op.isDeconvolution:
          ret = _op.nn.conv2d_transpose(
              data=inexpr, weight=weights, **params
          )
      else:
          ret = _op.nn.conv2d(data=inexpr, weight=weights, **params)
      if op.hasBias:
          biases = etab.new_const(list(op.bias.floatValue))
          ret = _op.nn.bias_add(ret, biases)
  
      return ret
  
imports: import math
  import numpy
  import tvm
  from tvm.ir import IRModule
  from ..None import analysis
  from ..None import expr
  from ..None import function
  from ..None import op
  from ...None import nd
  from ..._ffi import base
  from .common import ExprTable
  from .common import infer_shape
label_desc: Use image node_id 3 for calling a global function with example usage: _ConvolutionLayerParams(op, inexpr, etab) and returns: ret