code: def process_inline_mutation(model: GraphModelSpace) -> List[Mutator]:
      """Generate mutators based on the parsed model space.
  
      Model space should already have some hints on where the mutators should be plugged in.
      This function will generate the mutators based on those hints.
      """
  
      applied_mutators = []
  
      assert (
          label_scope.current() is None
      ), "label_scope should be empty before processing inline mutation."
  
      ic_nodes = _group_by_label(
          model.get_nodes_by_type(
              "__torch__.nni.nas.nn.pytorch.choice.InputChoice"
          )
      )
      for node_list in ic_nodes:
          assert _is_all_equal(
              map(
                  lambda node: node.operation.parameters[
                      "n_candidates"
                  ],
                  node_list,
              )
          ) and _is_all_equal(
              map(
                  lambda node: node.operation.parameters["n_chosen"],
                  node_list,
              )
          ), "Input choice with the same label must have the same number of candidates."
          mutator = InputChoiceMutator(node_list)
          applied_mutators.append(mutator)
  
      # `pc_nodes` are arguments of basic units. They can be compositions.
      pc_nodes: List[Tuple[Node, str, MutableExpression]] = []
      for node in model.get_nodes():
          # arguments used in operators like Conv2d
          # argument `valuechoice` used in generated repeat cell
          for name, choice in node.operation.parameters.items():
              if isinstance(choice, MutableExpression):
                  # e.g., (conv_node, "out_channels", ValueChoice([1, 3]))
                  pc_nodes.append((node, name, choice))
  
      # Break `pc_nodes` down to leaf value choices. They should be what we want to sample.
      leaf_value_choices: Dict[str, List[Any]] = {}
      for _, __, choice in pc_nodes:
          for inner_choice in choice.simplify().values():
              if not isinstance(inner_choice, Categorical):
                  raise TypeError(
                      f"Arguments in basic units only support expressions made up of choices, but {inner_choice} found."
                  )
              if inner_choice.label not in leaf_value_choices:
                  leaf_value_choices[
                      inner_choice.label
                  ] = inner_choice.values
              else:
                  assert (
                      leaf_value_choices[inner_choice.label]
                      == inner_choice.values
                  ), (
                      "Value choice with the same label must have the same candidates, but found "
                      f"{leaf_value_choices[inner_choice.label]} vs. {inner_choice.values}"
                  )
  
      for label, candidates in leaf_value_choices.items():
          applied_mutators.append(
              ParameterChoiceLeafMutator(candidates, label)
          )
  
      # in the end, add another parameter choice mutator for "real" mutations
      if pc_nodes:
          applied_mutators.append(
              ParameterChoiceMutator(
                  [(node, name) for node, name, _ in pc_nodes]
              )
          )
  
      # apply layer choice at last as it will delete some nodes
      lc_nodes = _group_by_label(
          filter(
              lambda d: d.operation.parameters.get("mutation")
              == "layerchoice",
              model.get_nodes_by_type("_cell"),
          )
      )
      for node_list in lc_nodes:
          assert _is_all_equal(
              map(
                  lambda node: len(
                      node.operation.parameters["candidates"]
                  ),
                  node_list,
              )
          ), "Layer choice with the same label must have the same number of candidates."
          mutator = LayerChoiceMutator(node_list)
          applied_mutators.append(mutator)
  
      repeat_nodes = _group_by_label(
          filter(
              lambda d: d.operation.parameters.get("mutation")
              == "repeat",
              model.get_nodes_by_type("_cell"),
          )
      )
      for node_list in repeat_nodes:
          # this check is not completely reliable, because it only checks max and min
          assert _is_all_equal(
              map(
                  lambda node: node.operation.parameters["max_depth"],
                  node_list,
              )
          ) and _is_all_equal(
              map(
                  lambda node: node.operation.parameters["min_depth"],
                  node_list,
              )
          ), "Repeat with the same label must have the same candidates."
          mutator = RepeatMutator(node_list)
          applied_mutators.append(mutator)
  
      return applied_mutators
  
imports: from __future__ import annotations
  from typing import Any, List, Tuple, Dict, Iterable, cast
  from nni.mutable import MutableExpression, Categorical, frozen_context, label_scope
  from nni.nas.space import Graph, GraphModelSpace, Node, StationaryMutator, Mutator
  from nni.nas.space.graph_op import Cell
label_desc: Use image node_id 1 for calling a global function with example usage: process_inline_mutation(model) and returns: applied_mutators