code: def test_saturation():
      # Same params
      data_dtype = "uint8"
      lhs_scale = rhs_scale = output_scale = 0.125
      lhs_zero_point = rhs_zero_point = output_zero_point = 0
  
      x = relay.var("x", shape=(1, 4), dtype=data_dtype)
      y = relay.var("y", shape=(1, 4), dtype=data_dtype)
      z = relay.qnn.mul(
          lhs=x,
          rhs=y,
          lhs_scale=relay.const(lhs_scale, "float32"),
          lhs_zero_point=relay.const(lhs_zero_point, "int32"),
          rhs_scale=relay.const(rhs_scale, "float32"),
          rhs_zero_point=relay.const(rhs_zero_point, "int32"),
          output_scale=relay.const(output_scale, "float32"),
          output_zero_point=relay.const(output_zero_point, "int32"),
      )
  
      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"]
  
      x_data = np.array((255, 1, 1, 0)).reshape((1, 4))
      y_data = np.array((255, 255, 128, 0)).reshape((1, 4))
  
      x_rec = recover(x_data, lhs_scale, lhs_zero_point)
      y_rec = recover(y_data, rhs_scale, rhs_zero_point)
  
      golden = generate_golden_output(
          x_rec, y_rec, output_scale, output_zero_point
      )
  
      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(), np.uint8(golden))
  
      # Same params, different scale
  
      lhs_scale = rhs_scale = 0.125
      output_scale = 0.25
  
      z = relay.qnn.mul(
          lhs=x,
          rhs=y,
          lhs_scale=relay.const(lhs_scale, "float32"),
          lhs_zero_point=relay.const(lhs_zero_point, "int32"),
          rhs_scale=relay.const(rhs_scale, "float32"),
          rhs_zero_point=relay.const(rhs_zero_point, "int32"),
          output_scale=relay.const(output_scale, "float32"),
          output_zero_point=relay.const(output_zero_point, "int32"),
      )
  
      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"]
  
      x_data = np.array((255, 1, 1, 0)).reshape((1, 4))
      y_data = np.array((255, 255, 127, 0)).reshape((1, 4))
  
      x_rec = recover(x_data, lhs_scale, lhs_zero_point)
      y_rec = recover(y_data, rhs_scale, rhs_zero_point)
  
      golden = generate_golden_output(
          x_rec, y_rec, output_scale, output_zero_point
      )
  
      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(), np.uint8(golden))
  
      # All params different
  
      lhs_scale = 0.5
      rhs_scale = 0.25
      output_scale = 0.125
  
      z = relay.qnn.mul(
          lhs=x,
          rhs=y,
          lhs_scale=relay.const(lhs_scale, "float32"),
          lhs_zero_point=relay.const(lhs_zero_point, "int32"),
          rhs_scale=relay.const(rhs_scale, "float32"),
          rhs_zero_point=relay.const(rhs_zero_point, "int32"),
          output_scale=relay.const(output_scale, "float32"),
          output_zero_point=relay.const(output_zero_point, "int32"),
      )
  
      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"]
  
      x_data = np.array((255, 0, 1, 0)).reshape((1, 4))
      y_data = np.array((0, 128, 64, 0)).reshape((1, 4))
  
      x_rec = recover(x_data, lhs_scale, lhs_zero_point)
      y_rec = recover(y_data, rhs_scale, rhs_zero_point)
  
      golden = generate_golden_output(
          x_rec, y_rec, output_scale, output_zero_point
      )
  
      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(), np.uint8(golden))
  
file_path: tvm/tests/python/relay/test_op_qnn_mul.py
imports: import tvm
  from tvm import te
  import numpy
  from tvm import relay
  from tvm.contrib import graph_executor
  import tvm.topi.testing
label_desc: Use image node_id 5 for calling a global function with example usage: test_saturation() without return types