code: def schedule_conv_NCHWc_cpu_common_int8(
      s,
      cfg,
      data_vec,
      kernel_vec,
      conv_out,
      last,
      int32_lanes=16,
      int8_elems=4,
      intrin=None,
      inline_fused=True,
      mem_scope="global",
  ):
      """
      Defines the schedule for INT8 for Intel and ARM machines
      Uses the Intel/ARM intrinsics to use INT8 operations
      More details - https://software.intel.com/en-us/articles/
      lower-numerical-precision-deep-learning-inference-and-training
      """
      if isinstance(cfg["tile_ow"], int):
          reg_n = cfg["tile_ow"]
      else:
          reg_n = cfg["tile_ow"].size[-1]
  
      if isinstance(cfg["unroll_kw"], (int, bool)):
          unroll_kw = cfg["unroll_kw"]
      else:
          unroll_kw = cfg["unroll_kw"].val
  
      _, _, _, _, ic_bn = get_const_tuple(data_vec.shape)
      _, _, _, _, oc_bn = get_const_tuple(conv_out.shape)
  
      # schedule pad
      if (
          isinstance(s[data_vec].op, te.tensor.ComputeOp)
          and "pad" in data_vec.op.tag
      ):
          batch, ic_chunk, ih, iw, ic_block = s[data_vec].op.axis
          parallel_axis = s[data_vec].fuse(batch, ic_chunk, ih)
          s[data_vec].parallel(parallel_axis)
          data_vec = data_vec.op.input_tensors[0]
  
      if autotvm.GLOBAL_SCOPE.in_tuning:
          # only in autotuning, input data of conv2d_NCHWc will be 4-D.
          # skip this part during tuning to make records accurate.
          # this part will be folded during Relay fold_constant pass.
          if isinstance(data_vec.op, te.tensor.ComputeOp):
              s[data_vec].pragma(
                  s[data_vec].op.axis[0], "debug_skip_region"
              )
          if isinstance(kernel_vec.op, te.tensor.ComputeOp):
              s[kernel_vec].pragma(
                  s[kernel_vec].op.axis[0], "debug_skip_region"
              )
      elif (
          isinstance(kernel_vec.op, te.tensor.ComputeOp)
          and kernel_vec.name == "kernel_vec"
      ):
          # data and kernel are not pre-computed, schedule layout transform here.
          # this should only be used by x86 conv2d_nchw, which is for
          # testing purpose.
          batch, ic_chunk, ih, iw, ic_block = s[data_vec].op.axis
          parallel_axis = s[data_vec].fuse(batch, ic_chunk, ih)
          s[data_vec].parallel(parallel_axis)
  
          # conv2d_nchwc_int8 has 7D kernel
          oc_chunk, ic_chunk, oh, ow, ic_block, oc_block, _ = s[
              kernel_vec
          ].op.axis
          s[kernel_vec].reorder(
              oc_chunk, oh, ic_chunk, ow, ic_block, oc_block
          )
          oc_bn = cfg["tile_oc"].size[-1]
          if oc_bn > 1:
              s[kernel_vec].vectorize(oc_block)
          parallel_axis = s[kernel_vec].fuse(oc_chunk, oh)
          s[kernel_vec].parallel(parallel_axis)
  
      # schedule 5-D NCHW[x]c conv
      C, O = conv_out, last
      CC = s.cache_write(C, mem_scope)
  
      batch, oc_chunk, oh, ow, oc_block = s[C].op.axis
      ow_chunk, ow_block = s[C].split(ow, factor=reg_n)
      s[C].reorder(oc_chunk, oh, ow_chunk, ow_block, oc_block)
      parallel_axis = s[C].fuse(batch, oc_chunk, oh)
      s[C].vectorize(oc_block)
      if C == O:
          s[C].parallel(parallel_axis)
  
      s[CC].compute_at(s[C], parallel_axis)
      _, oc_chunk, oh, ow, oc_block = s[CC].op.axis
      kh, kw, ic_outer, ic_f_inner, ic_s_inner = s[CC].op.reduce_axis
  
      ow_chunk, ow_block = s[CC].split(ow, factor=reg_n)
  
      assert (
          oc_bn % int32_lanes == 0
      ), f"oc_bn={oc_bn} % int32_lanes={int32_lanes} != 0"
      assert (
          ic_bn % int8_elems == 0
      ), f"ic_bn={ic_bn} % int8_elems={int8_elems} != 0"  # (u)int8 elements in (u)int32
  
      oc_f_inner, oc_s_inner = s[CC].split(oc_block, factor=int32_lanes)
  
      if unroll_kw:
          s[CC].reorder(
              oc_chunk,
              oh,
              ow_chunk,
              ic_outer,
              kh,
              ic_f_inner,
              kw,
              ow_block,
              oc_f_inner,
              oc_s_inner,
              ic_s_inner,
          )
          s[CC].unroll(kw)
      else:
          s[CC].reorder(
              oc_chunk,
              oh,
              ow_chunk,
              ic_outer,
              kh,
              kw,
              ic_f_inner,
              ow_block,
              oc_f_inner,
              oc_s_inner,
              ic_s_inner,
          )
  
      if intrin is not None:
          s[CC].tensorize(oc_s_inner, intrin)
      s[CC].unroll(ow_block)
      s[CC].unroll(oc_f_inner)
  
      if C != O:
          out_ndim = len(s[O].op.axis)
          if out_ndim == 5:
              batch, oc_chunk, oh, ow, oc_block = s[O].op.axis
              ow_chunk, ow_block = s[O].split(ow, factor=reg_n)
              s[O].reorder(oc_chunk, oh, ow_chunk, ow_block, oc_block)
          elif out_ndim == 4:
              batch, oc, oh, ow = s[O].op.axis
              ow_chunk, ow_block = s[O].split(ow, factor=reg_n)
              oc_chunk, oc_block = s[O].split(oc, factor=oc_bn)
              s[O].reorder(oc_chunk, oh, ow_chunk, ow_block, oc_block)
          else:
              raise ValueError(f"Unsupported output ndim: {out_ndim}")
          parallel_axis = s[O].fuse(batch, oc_chunk, oh)
          if inline_fused:
              s[C].compute_at(s[O], ow_block)
          else:
              s[C].compute_at(s[O], parallel_axis)
          s[O].vectorize(oc_block)
          s[O].parallel(parallel_axis)
  
      return s
  
file_path: tvm/python/tvm/topi/generic/conv2d.py
imports: from tvm import te
  from tvm import autotvm
  from tvm import relay
  from tvm.autotvm.task.space import SplitEntity, OtherOptionEntity
  from ..utils import get_const_tuple, traverse_inline
  from ..nn.utils import get_pad_tuple
label_desc: Use image node_id 3 for calling a global function with example usage: schedule_conv_NCHWc_cpu_common_int8(s, cfg, data_vec, kernel_vec, conv_out, last, int32_lanes, int8_elems, intrin, inline_fused, mem_scope) and returns: s