code: def _schedule_reduce(sch, op, is_idx_reduce=False):
      if is_idx_reduce:
          real_out = op.output(0)
          fused = sch[real_out].fuse(*sch[real_out].op.axis)
          out = op.input_tensors[0]
      else:
          out = op.output(0)
  
      const_shape = True
      out_shape = get_const_tuple(out.shape)
      for d in out_shape:
          if not isinstance(d, int):
              const_shape = False
              break
  
      if const_shape:
          naxes = len(sch[out].op.axis)
          parallelism = 1
          fuse_axes = []
          # We choose a heuristic number 128 to limit the maximum parallelism
          while len(fuse_axes) < naxes and parallelism < 128:
              ivar = sch[out].op.axis[len(fuse_axes)]
              parallelism *= int(ivar.dom.extent)
              fuse_axes.append(ivar)
          fused = sch[out].fuse(*fuse_axes)
          sch[out].parallel(fused)
      else:
          if len(sch[out].op.axis) >= 5:
              # avoid too many parallelism
              fused = sch[out].fuse(
                  sch[out].op.axis[0],
                  sch[out].op.axis[1],
                  sch[out].op.axis[2],
              )
              sch[out].parallel(fused)
          else:
              fused = sch[out].fuse(*sch[out].op.axis)
              sch[out].parallel(fused)
  
imports: import tvm
  from tvm import te
  from .injective import schedule_injective_from_existing
  from ..None import tag
  from ..utils import get_const_tuple
label_desc: Use image node_id 1 for calling a global function with example usage: _schedule_reduce(sch, op, is_idx_reduce) without return types