class_docstr: Convert a pytorch model to nni ir along with input/output shape info.
  Based ir acquired through ``torch.jit.script``
  and shape info acquired through ``torch.jit.trace``.
  
  .. warning::
  
      Known issues:
  
      1. ``InputChoice`` and ``ValueChoice`` not supported yet.
      2. Currently random inputs are fed while tracing layerchoice.
         If forward path of candidates depends on input data, then wrong path will be traced.
         This will result in incomplete shape info.
code: def propagate_shape(self, ir_model: GraphModelSpace):
      def propagate_shape_for_graph(graph: "Graph"):
          if graph == ir_model.root_graph:
              return
  
          graph_node = ir_model.get_node_by_name(graph.name)
          assert (
              graph_node is not None
          ), f"Cannot find a node with name {graph.name}"
          if not _without_shape_info(graph_node):
              return
  
          if is_layerchoice_node(graph_node):
              cand_name = graph_node.operation.parameters["candidates"][
                  0
              ]
              cand_node = ir_model.get_node_by_name(cand_name)
              assert (
                  cand_node is not None
              ), f"Cannot find a node with name {cand_name}"
              if _without_shape_info(cand_node):
                  propagate_shape_for_graph(ir_model.graphs[cand_name])
              graph_node.operation.attributes[
                  "input_shape"
              ] = cand_node.operation.attributes["input_shape"]
              graph_node.operation.attributes[
                  "output_shape"
              ] = cand_node.operation.attributes["output_shape"]
          else:
              input_shape = [[]] * len(
                  graph.input_node.operation.io_names or []
              )
              output_shape = [[]] * len(
                  graph.output_node.operation.io_names or []
              )
              for edge in graph.input_node.outgoing_edges:
                  node = edge.tail
                  if _without_shape_info(node):
                      if node.name in ir_model.graphs:
                          propagate_shape_for_graph(
                              ir_model.graphs[node.name]
                          )
                  if node.operation.attributes["input_shape"]:
                      input_shape[
                          edge.head_slot or 0
                      ] = node.operation.attributes["input_shape"][
                          edge.tail_slot or 0
                      ]
              graph_node.operation.attributes[
                  "input_shape"
              ] = input_shape
              for edge in graph.output_node.incoming_edges:
                  node = edge.head
                  if _without_shape_info(node):
                      if node.name in ir_model.graphs:
                          propagate_shape_for_graph(
                              ir_model.graphs[node.name]
                          )
                  if node.operation.attributes["output_shape"]:
                      output_shape[
                          edge.tail_slot or 0
                      ] = node.operation.attributes["output_shape"][
                          edge.head_slot or 0
                      ]
              graph_node.operation.attributes[
                  "output_shape"
              ] = output_shape
  
          propagate_shape_for_graph(graph_node.graph)
  
      # propagate from node to graph
      for node in ir_model.get_nodes():
          propagate_shape_for_graph(node.graph)
  
imports: import re
  import torch
  from nni.nas.space.graph import Graph, GraphModelSpace, Node, Cell, Operation
  from nni.nas.nn.pytorch import InputChoice, MutationAnchor, LayerChoice, MutableModule, Repeat
  from nni.nas.utils import get_init_parameters_or_fail, get_importable_name
  from .op_types import MODULE_EXCEPT_LIST, OpTypeName
  from .utils import _convert_name, build_full_name, _without_shape_info, _extract_info_from_trace_node, get_full_name_by_scope_name, is_layerchoice_node, match_node, build_cand_name, build_python_name
label_desc: Use image node_id 4 for calling the GraphConverterWithShape obj's underlying member method code with example usage: obj.propagate_shape(ir_model) without return types