code: def apply_proposal(proposal: Proposal, sch: te.Schedule) -> None:
      """Apply a Proposal to a Schedule, converting all the Plans into TE scheduling instructions.
  
      Note that the Schedule is mutated in-place.
  
      Parameters
      ----------
      proposal : Proposal
          The Proposal to apply to the Schedule.
      sch : te.Schedule
          The Schedule to apply to Proposal to.
  
      """
      for plan in proposal.plans:
          for part in plan.part_group:
              if isinstance(part, EthosuPart):
                  tensor_config = plan.tensor_configs[
                      part.output_tensor
                  ]
                  stripe_config = tensor_config.stripe_configs[0]
                  buffer_mode = tensor_config.buffer_mode
                  block_config = part.get_block_config(stripe_config)
                  compute_cycles = part.get_performance_info(
                      stripe_config, buffer_mode
                  ).compute_cycles
                  iv = part.subgraph.output_tensor.op.axis[0]
                  block_shape = block_config.output_shape
                  if len(block_shape) == 4:
                      height, width, depth = block_shape[1:]
                  else:
                      height = block_shape[1]
                      width = block_shape[3]
                      depth = block_shape[2] * block_shape[4]
                  sch[part.subgraph.output_tensor].pragma(
                      iv, "block_config_height", height
                  )
                  sch[part.subgraph.output_tensor].pragma(
                      iv, "block_config_width", width
                  )
                  sch[part.subgraph.output_tensor].pragma(
                      iv, "block_config_depth", depth
                  )
  
                  # Attach AttrStmt directly to npu op so it isn't removed by ReplaceOperators
                  npu_op = part.subgraph.output_tensor.op.input_tensors[
                      0
                  ].op.input_tensors[0]
                  # Force the pragma to interpret the compute cycles as an int64 value
                  compute_cycles_int64_cast = tvm.tir.IntImm(
                      "int64", compute_cycles
                  )
                  sch[npu_op].pragma(
                      npu_op.op.axis[0],
                      "compute_cycles_hint",
                      compute_cycles_int64_cast,
                  )
  
          output_tensor_config = plan.output_config
          output_tensor = output_tensor_config.tensor
          output_part = output_tensor.producers[0]
          if output_part.in_line:
              continue
          stripe_config = output_tensor_config.stripe_configs[0]
          stripe_shape = [int(x) for x in stripe_config.shape]
          stripe_stage, stripe_axis = stripe_part(
              output_part, stripe_shape, sch
          )
          copy_te_tensors = []
          compute_cycles_hints = []
          readers = defaultdict(list)
          for part in plan.part_group:
              if part != output_part:
                  cascade_part(part, stripe_stage, stripe_axis, sch)
  
              update_readers(part, readers)
              for i, input_tensor in enumerate(part.input_tensors):
                  tensor_config = plan.tensor_configs[input_tensor]
                  if (
                      tensor_config.home_region
                      != tensor_config.copy_region
                  ):
                      copy_te_tensors.append(
                          part.subgraph.input_tensors[i]
                      )
  
                      compute_cycles_hint, _ = get_copy_cycles_hint(
                          tensor_config
                      )
                      compute_cycles_hints.append(compute_cycles_hint)
  
          for te_tensor, compute_cycles_hint in zip(
              copy_te_tensors, compute_cycles_hints
          ):
              copy_stage = sch.cache_read(
                  te_tensor, "global", readers[te_tensor]
              )
              sch[copy_stage].pragma(
                  copy_stage.op.axis[0],
                  "compute_cycles_hint",
                  compute_cycles_hint,
              )
              sch[copy_stage].compute_at(stripe_stage, stripe_axis)
  
imports: from typing import Tuple, List, Dict, DefaultDict
  from collections import defaultdict
  import time
  import numpy
  import tvm
  from tvm import te
  from tvm import tir
  from tvm import PoolInfo
  from .cascader_options import CascaderOptions
  from .graph import CascaderGraph, Part, Tensor, TESubgraph
  from .parts import EthosuPart
  from .tensor_config import MemoryRegion
  from .proposal import Proposal
  from .proposal_generator import generate_proposals
  from .plan_generator import get_copy_cycles_hint
  from .graph import create_cascader_graph
  from .device_config import EthosuDeviceConfig
  from .logging import Logging
label_desc: Use image node_id 5 for calling a global function with example usage: apply_proposal(proposal, sch) without return types