code: def _schedule_packed_8x8x32_conv2d():
      """Manually schedule a conv2d block, created from TE compute op via CreatePrimFunc,
      using 8x8x32 packed layout.
      """
  
      def schedule_fn(
          sch, conv2d_block: Optional[BlockRV] = None
      ) -> bool:
          if conv2d_block is None:
              if has_block(sch, "conv2d_NCHWc_int8"):
                  conv2d_block = sch.get_block("conv2d_NCHWc_int8")
              else:
                  return False
  
          assert (
              "conv2d_NCHWc_int8"
              in sch.get(conv2d_block).annotations["schedule_rule"]
          )
  
          # Apply scheduling
  
          post_blocks = sch.get_consumers(conv2d_block)
          if len(post_blocks) > 0:
              # Fuse all intermediate post ops into the last op.
              # This is equivalent to the traverse_inline function used in TE schedules.
              while True:
                  next_post_blocks = []
                  for post_block in post_blocks:
                      next_consumers = sch.get_consumers(post_block)
                      if len(next_consumers) > 0:
                          sch.compute_inline(post_block)
                      next_post_blocks += next_consumers
                  if len(next_post_blocks) == 0:
                      assert len(post_blocks) == 1
                      outer_block = post_blocks[0]
                      break
                  post_blocks = next_post_blocks
          else:
              outer_block = conv2d_block
  
          # Move the conv2d mma into the injective post mma compute block
          if outer_block != conv2d_block:
              loops = sch.get_loops(outer_block)
              # TODO(csullivan): Currently does all post conv2d mma steps
              # directly after accumulation for one spatial pixel. May
              # be desirable to do this with coarser spatial granularity
              sch.compute_at(conv2d_block, loops[4])
  
          def index_map_nchw32c_nchw8h8w32c(
              n_batch, channel, height, width, channel_32
          ):
              return [
                  n_batch,
                  channel,
                  height // 8,
                  width // 8,
                  height % 8,
                  width % 8,
                  channel_32,
              ]
  
          # Add cache for input and output activation layout transform,
          # note that weight is already in correct layout
          # pylint: disable=unused-variable
          input_cache = sch.cache_read(conv2d_block, 0, "global.vtcm")
          output_cache = sch.cache_write(outer_block, 0, "global.vtcm")
          # Transform the layout of the input
          sch.transform_layout(
              conv2d_block,
              ("read", 0),
              index_map=index_map_nchw32c_nchw8h8w32c,
              pad_value=0,
          )
          # Transform the layout of the int32 accumulator
          sch.transform_layout(
              conv2d_block,
              ("write", 0),
              index_map=index_map_nchw32c_nchw8h8w32c,
              pad_value=0,
          )
          # Transform the layout of the output
          sch.transform_layout(
              outer_block,
              ("write", 0),
              index_map=index_map_nchw32c_nchw8h8w32c,
              pad_value=0,
          )
          return True
  
      return schedule_fn
  
imports: import os
  import tempfile
  from types import MappingProxyType
  from typing import Any, Mapping, Optional
  import numpy
  import pytest
  import tvm
  import tvm.testing
  from tvm import meta_schedule
  from tvm import relay
  from tvm._ffi import register_func
  from tvm.contrib.hexagon.meta_schedule import get_hexagon_local_builder, get_hexagon_rpc_runner
  from tvm.meta_schedule import postproc, schedule_rule
  from tvm.meta_schedule.utils import cpu_count
  from tvm.tir.schedule import BlockRV, Schedule
  from tvm.tir.schedule.analysis import has_block
  from tvm.tir.tensor_intrin.hexagon import VRMPY_u8i8i32_INTRIN, VRMPY_u8u8i32_INTRIN, VRMPY_u8i8i32_VTCM_INTRIN
  from ..infrastructure import get_hexagon_target
label_desc: Use image node_id 5 for calling a global function with example usage: _schedule_packed_8x8x32_conv2d() and returns: schedule_fn, True, list, False