code: def qnn_subtract_driver(
      x_datas, y_datas, golden_outputs, scale_and_zp, data_dtype="uint8"
  ):
      # all x, y and golden outputs should be of the same length
      assert len(x_datas) == len(y_datas)
      assert len(y_datas) == len(golden_outputs)
  
      x = relay.var("x", shape=(1, 4), dtype=data_dtype)
      y = relay.var("y", shape=(1, 4), dtype=data_dtype)
      lhs_scale = relay.const(scale_and_zp["lhs_scale"], "float32")
      lhs_zp = relay.const(scale_and_zp["lhs_zp"], "int32")
      rhs_scale = relay.const(scale_and_zp["rhs_scale"], "float32")
      rhs_zp = relay.const(scale_and_zp["rhs_zp"], "int32")
      output_scale = relay.const(
          scale_and_zp["output_scale"], "float32"
      )
      output_zp = relay.const(scale_and_zp["output_zp"], "int32")
      z = relay.qnn.subtract(
          lhs=x,
          rhs=y,
          lhs_scale=lhs_scale,
          lhs_zero_point=lhs_zp,
          rhs_scale=rhs_scale,
          rhs_zero_point=rhs_zp,
          output_scale=output_scale,
          output_zero_point=output_zp,
      )
      func = relay.Function([x, y], z)
      mod = tvm.IRModule.from_expr(func)
      mod = relay.transform.InferType()(mod)
      mod = relay.qnn.transform.CanonicalizeOps()(mod)
      func = mod["main"]
      for i in range(0, len(x_datas)):
          x_data = x_datas[i]
          y_data = y_datas[i]
          golden_output = golden_outputs[i]
          op_res = relay.create_executor(
              "graph", device=tvm.cpu(0), target="llvm"
          ).evaluate(func)(x_data, y_data)
          np.testing.assert_equal(op_res.numpy(), golden_output)
  
imports: import tvm
  import numpy
  from tvm import relay
label_desc: Use image node_id 1 for calling a global function with example usage: qnn_subtract_driver(x_datas, y_datas, golden_outputs, scale_and_zp, data_dtype) without return types