class_docstr: An subtask graph builder which build subtask graph for chunk graph based on passed band_resource.
  
  If push shuffle is used, this builder will validate predecessors orders consistency of ShuffleProxy between
  chunk graph and generated subtask graph.
code: def _gen_map_reduce_info(
      self, chunk: ChunkType, assign_results: Dict[ChunkType, BandType]
  ):
      reducer_ops = OrderedSet(
          [
              c.op
              for c in self._chunk_graph.successors(chunk)
              if c.op.stage == OperandStage.reduce
          ]
      )
      map_chunks = [
          c
          for c in self._chunk_graph.predecessors(chunk)
          if (c.op.stage == OperandStage.map) or c.is_mapper
      ]
      map_reduce_id = self.next_map_reduce_id()
      for map_chunk in map_chunks:
          # record analyzer map reduce id for mapper op
          # copied chunk exists because map chunk must have
          # been processed before shuffle proxy
          copied_map_chunk = self._chunk_to_copied[map_chunk]
          if not hasattr(
              copied_map_chunk, "extra_params"
          ):  # pragma: no cover
              copied_map_chunk.extra_params = dict()
          copied_map_chunk.extra_params[
              "analyzer_map_reduce_id"
          ] = map_reduce_id
      reducer_bands = [
          assign_results[r.outputs[0]] for r in reducer_ops
      ]
      map_reduce_info = MapReduceInfo(
          map_reduce_id=map_reduce_id,
          reducer_indexes=[
              reducer_op.reducer_index for reducer_op in reducer_ops
          ],
          reducer_bands=reducer_bands,
      )
      self._map_reduce_id_to_infos[map_reduce_id] = map_reduce_info
  
imports: import itertools
  import logging
  from collections import deque, defaultdict
  from typing import Dict, List, Tuple, Type, Union
  from ....config import Config
  from ....core import ChunkGraph, ChunkType, enter_mode, DAG
  from ....core.operand import Fetch, VirtualOperand, LogicKeyGenerator, MapReduceOperand, OperandStage, ShuffleProxy, ShuffleFetchType
  from ....lib.ordered_set import OrderedSet
  from ....resource import Resource
  from ....typing import BandType, OperandType
  from ....utils import build_fetch, build_fetch_shuffle, tokenize
  from ...subtask import SubtaskGraph, Subtask
  from ..core import Task, new_task_id, MapReduceInfo
  from .assigner import AbstractGraphAssigner, GraphAssigner
  from .fusion import Coloring
label_desc: Use image node_id 9 for calling the GraphAnalyzer obj's underlying member method code with example usage: obj._gen_map_reduce_info(chunk, assign_results) without return types