code: def _schedule_spatial_pack(
      cfg, s, data_vec, kernel_vec, conv, output, last
  ):
      """schedule implementation"""
      n, co, oh, ow, vh, vw, vc = s[conv].op.axis
      kh, kw = s[conv].op.reduce_axis
  
      if data_vec.op.name == "data_vec_undilated":
          _, dv_oh, dv_ow, dv_c, _, _, dv_vh, dv_vw = s[
              data_vec
          ].op.axis
      else:
          _, dv_oh, dv_ow, dv_c, dv_vh, dv_vw = s[data_vec].op.axis
  
      data_pad = data_vec.op.input_tensors[0]
      if data_pad.op.name == "data_pad":
          assert isinstance(data_pad.op, tvm.te.ComputeOp)
          has_padding = True
      else:
          assert isinstance(data_pad.op, tvm.te.PlaceholderOp)
          has_padding = False
  
      cfg.define_knob("data_pad_inline", [0, 1, 2, 3, 4])
  
      if cfg["data_pad_inline"].val == 1 and has_padding:
          s[data_pad].compute_inline()
      if cfg["data_pad_inline"].val == 2 and has_padding:
          s[data_pad].vectorize(list(s[data_pad].op.axis)[-1])
      if cfg["data_pad_inline"].val == 3 and has_padding:
          s[data_pad].vectorize(list(s[data_pad].op.axis)[-1])
          s[data_pad].compute_at(s[data_vec], dv_oh)
      if cfg["data_pad_inline"].val == 4 and has_padding:
          s[data_pad].vectorize(list(s[data_pad].op.axis)[-1])
          s[data_pad].compute_at(s[data_vec], dv_ow)
  
      cfg.define_knob("data_vec_inline", [0, 1, 2, 3])
      if cfg["data_vec_inline"].val == 1:
          s[data_vec].compute_at(s[conv], oh)
      if cfg["data_vec_inline"].val == 2:
          s[data_vec].compute_at(s[conv], ow)
      if cfg["data_vec_inline"].val == 3:
          s[data_vec].compute_at(s[conv], co)
  
      # schedule conv
      cfg["reorder_0"].apply(
          s, conv, [n, co, oh, ow, kh, kw, vh, vw, vc]
      )
      cfg["ann_reduce"].apply(
          s,
          conv,
          [kh, kw],
          axis_lens=[
              get_const_int(kh.dom.extent),
              get_const_int(kw.dom.extent),
          ],
          max_unroll=16,
          cfg=cfg,
      )
      cfg["ann_spatial"].apply(
          s,
          conv,
          [vh, vw, vc],
          axis_lens=[
              cfg["tile_oh"].size[-1],
              cfg["tile_ow"].size[-1],
              cfg["tile_co"].size[-1],
          ],
          max_unroll=16,
          cfg=cfg,
      )
  
      # schedule fusion
      n, co, h, w = s[last].op.axis
      co, vc = cfg["tile_co"].apply(s, last, co)
      oh, vh = cfg["tile_oh"].apply(s, last, h)
      ow, vw = cfg["tile_ow"].apply(s, last, w)
      cfg["reorder_1"].apply(s, last, [n, co, oh, ow, vh, vw, vc])
      if last != output:
          s[output].compute_inline()
          cfg["ann_spatial"].apply(
              s,
              last,
              [vh, vw, vc],
              axis_lens=[
                  cfg["tile_oh"].size[-1],
                  cfg["tile_ow"].size[-1],
                  cfg["tile_co"].size[-1],
              ],
              max_unroll=16,
              cfg=cfg,
          )
      else:
          s[last].vectorize(vw)
      cfg.define_knob("conv_inline", [0, 1, 2, 3])
      if cfg["conv_inline"].val == 1:
          s[conv].compute_at(s[last], ow)
      if cfg["conv_inline"].val == 2:
          s[conv].compute_at(s[last], oh)
      if cfg["conv_inline"].val == 3:
          s[conv].compute_at(s[last], co)
  
      # mark parallel
      s[last].parallel(co)
  
      if data_vec.op.name == "data_vec_undilated":
          _, h, _, _, _, _, _, _ = s[data_vec].op.axis
      else:
          _, h, _, _, _, _ = s[data_vec].op.axis
      s[data_vec].parallel(h)
  
      if kernel_vec.op.name == "kernel_vec":
          co, _, _, _, _ = s[kernel_vec].op.axis
          if autotvm.GLOBAL_SCOPE.in_tuning:
              # kernel packing will be pre-computed during compilation, so we skip
              # this part to make tuning records correct
              s[kernel_vec].pragma(co, "debug_skip_region")
          else:
              s[kernel_vec].parallel(co)
  
      return s
  
file_path: tvm/python/tvm/topi/arm_cpu/depthwise_conv2d.py
imports: import tvm
  from tvm.target import Target
  from tvm import te
  from tvm import autotvm
  from tvm.autotvm.task.space import SplitEntity, OtherOptionEntity
  from ..None import nn
  from ..utils import traverse_inline, get_const_tuple, get_const_int
  from ..nn.utils import get_pad_tuple
  from .tensor_intrin import smlal_int16_int32
  from .mprofile.dsp.depthwise_conv2d import depthwise_conv2d_nhwc_dsp_compute, depthwise_conv2d_nhwc_dsp_schedule
label_desc: Use image node_id 8 for calling a global function with example usage: _schedule_spatial_pack(cfg, s, data_vec, kernel_vec, conv, output, last) and returns: s