code: def helper_change_dtypes_to_be_same(attrs, inputs, types, relay_op):
      """Sometimes MxNet + MLDNN can lead to uint8 x int8 datatypes for the conv inputs. However,
      many devices like ARM prefer the datatypes to be same for the HW units. This helper transforms
      conv2d/dense such that both the dtypes are same.
  
      Parameters
      ----------
      attrs : tvm.ir.Attrs
          Attributes of current convolution
      inputs : list of tvm.relay.Expr
          The args of the Relay expr to be legalized
      types : list of types
          List of input and output types
  
      Returns
      -------
      result : tvm.relay.Expr
          The legalized expr
      """
  
      def _shift(data, zero_point, out_dtype):
          """Shifts (adds/subtracts) the qnn tensor by 128)"""
          if out_dtype == "uint8":
              shift = 128
          elif out_dtype == "int8":
              shift = -128
          else:
              raise ValueError("Unsupported out dtype.")
          data_modified = relay.cast(data, "int32")
          data_modified = relay.add(
              data_modified, relay.const(shift, "int32")
          )
          data_modified = relay.cast(data_modified, out_dtype)
          zero_point_val = get_scalar_from_constant(zero_point)
          zero_point_modified = relay.const(
              zero_point_val + shift, "int32"
          )
          return (data_modified, zero_point_modified)
  
      # Collect the dtypes.
      data_dtype = types[0].dtype
      kernel_dtype = types[1].dtype
  
      if data_dtype == kernel_dtype:
          return None
  
      # Collect the input exprs.
      (
          data,
          kernel,
          input_zero_point,
          kernel_zero_point,
          input_scale,
          kernel_scale,
      ) = inputs
  
      assert (
          "int8" in data_dtype and "int8" in kernel_dtype
      ), "Qnn Conv2D/Dense only accepts uint8 or int8 inputs"
  
      # Shift input if necessary.
      data, input_zero_point = _shift(
          data, input_zero_point, kernel_dtype
      )
  
      new_attrs = {k: attrs[k] for k in attrs.keys()}
      return relay_op(
          data,
          kernel,
          input_zero_point,
          kernel_zero_point,
          input_scale,
          kernel_scale,
          **new_attrs,
      )
  
imports: import numpy
  from scipy import special
  import tvm
  from tvm import relay
  from tvm._ffi.base import TVMError
  from tvm.relay.qnn.op.canonicalizations import create_integer_lookup_op
  from ....target.x86 import target_has_features
  from ....topi.utils import is_target
  from ..None import op
label_desc: Use image node_id 15 for calling a global function with example usage: helper_change_dtypes_to_be_same(attrs, inputs, types, relay_op) and returns: relay_op, data_modified,  zero_point_modified, None