code: def measure_compute_mad(
      total_item,
      item_per_thread,
      base_type,
      bits,
      lanes,
      target,
      target_host,
      remote,
      dev,
      n_times,
  ):
      """measure peak compute speed by computing mad for a type
  
      The IR for measurement is
  
      for each thread
          for i in 1..item_per_thread
              x = mad(x, x, y)
              y = mad(y, y, x)
  
      Parameters
      ----------
      total_item: int
          number of elements in input array
      item_per_thread: int
          number of operations each thread does
      base_type: str
          can be "int", "float"
      bits: int
          can be 16, 32
      lanes: int
         lane of the vector type, can be 1, 2, 4, 8, 16
      target: :any:`tvm.target.Target`
          the target and option of the compilation.
      target_host : str or :any:`tvm.target.Target`
          host compilation target
      remote: tvm.rpc.RPCSession
          if it is not None, use remote rpc session
      dev: Device
          the device of array
      n_times: int
          number of runs for taking mean
  
      Returns
      -------
      GOPS: float
           giga operation per second
      """
      target, target_host = Target.canon_target_and_host(
          target, target_host
      )
  
      n = total_item
  
      if bits >= 64 or lanes >= 16:
          n //= 2
  
      max_threads = target.max_num_threads
  
      base_type = str(base_type) + str(bits)
      dtype = base_type if lanes == 1 else base_type + "x" + str(lanes)
  
      def extern(ins, outs):
          # pylint: disable=unused-argument
          """construct measurement function by building IR directly"""
          ib = tvm.tir.ir_builder.create()
  
          bx = te.thread_axis("blockIdx.x")
          tx = te.thread_axis("threadIdx.x")
  
          ib.scope_attr(bx, "thread_extent", n // max_threads)
          ib.scope_attr(tx, "thread_extent", max_threads)
  
          idx = bx.var * max_threads + tx.var
  
          a = ib.allocate(dtype, (1), name="a", scope="local")
          b = ib.allocate(dtype, (1), name="b", scope="local")
  
          a[0] = outs[0].vload(idx, dtype)
          b[0] = outs[0].vload(idx, dtype)
  
          if base_type.find("float") != -1:
  
              def mad_func(x, y):
                  return x * x + y
  
          else:
  
              def mad_func(x, y):
                  return y * y + x
  
          for _ in range(item_per_thread // 4 // lanes):
              a[0] = mad_func(a[0], b[0])
              b[0] = mad_func(b[0], a[0])
  
          ib.emit(outs[0].vstore(idx, b[0]))
          return ib.get()
  
      y = te.extern((n,), [], extern, name="y", dtype=dtype)
      s = te.create_schedule(y.op)
  
      try:
          func = tvm.build(s, [y], target)
          func = _convert_to_remote(func, remote)
          time_f = func.time_evaluator(
              func.entry_name, dev, number=n_times
          )
          y = tvm.nd.empty((n,), dtype=dtype, device=dev)
          time = time_f(y).mean
      except tvm._ffi.base.TVMError:
          # build error (occur when device does not support half)
          return -1
  
      return 1.0 * (n * item_per_thread) / 1e9 / time
  
file_path: tvm/python/tvm/contrib/peak.py
imports: import logging
  import tvm
  from tvm import te
  from tvm.target import Target
  from .None import utils
  from ..None import rpc
label_desc: Use image node_id 4 for calling a global function with example usage: measure_compute_mad(total_item, item_per_thread, base_type, bits, lanes, target, target_host, remote, dev, n_times) and returns: unknown, ib, unknown, unknown, unknown