class_docstr: Execute an FX graph Node-by-Node with meta tensor and
  record the memory usage, FLOPs, and type of the result
  into the corresponding node.
  
  Usage:
      BATCH_SIZE = 2
      DIM_IN = 4
      DIM_HIDDEN = 16
      DIM_OUT = 16
      model = torch.nn.Sequential(
          torch.nn.Linear(DIM_IN, DIM_HIDDEN),
          torch.nn.Linear(DIM_HIDDEN, DIM_OUT),
          )
      input_sample = torch.rand(BATCH_SIZE, DIM_IN)
      gm = symbolic_trace(model)
      interp = MetaInfoProp(gm)
      interp.run(input_sample)
      print(interp.summary(format='kb'))    # don't panic if some statistics are 0.00 MB
  
  
      # output of above code is
          Op type       Op    Forward FLOPs    Backward FLOPs    FWD_OUT    FWD_TMP    BWD_OUT    BWD_TMP
      -----------  -------  ---------------  ----------------  ---------  ---------  ---------  ---------
      placeholder  input_1          0 FLOPs           0 FLOPs    0.00 KB    0.00 KB    0.00 KB    0.00 KB
      call_module       _0        128 FLOPs         288 FLOPs    0.12 KB    0.00 KB    0.34 KB    0.00 KB
      call_module       _1        512 FLOPs       1,056 FLOPs    0.12 KB    0.00 KB    1.19 KB    0.00 KB
           output   output          0 FLOPs           0 FLOPs    0.00 KB    0.00 KB    0.00 KB    0.00 KB
  Args:
       module (GraphModule): The module to be executed
docstr: Summarizes the memory and FLOPs statistics of the `GraphModule` in
  tabular format. Note that this API requires the ``tabulate`` module
  to be installed.
docstr_tok: ["Summarizes","the","memory","and","FLOPs","statistics","of","the","`","GraphModule","`","in","tabular","format",".","Note","that","this","API","requires","the","``","tabulate","``","module","to","be","installed","."]
code: def summary(self, unit: str = "MB") -> str:
      """
      Summarizes the memory and FLOPs statistics of the `GraphModule` in
      tabular format. Note that this API requires the ``tabulate`` module
      to be installed.
      """
      # https://github.com/pytorch/pytorch/blob/master/torch/fx/graph.py
      try:
          from tabulate import tabulate
      except ImportError:
          print(
              "`summary` relies on the library `tabulate`, "
              "which could not be found on this machine. Run `pip "
              "install tabulate` to install the library."
          )
  
      assert (
          self._is_proped
      ), "Please call `interp.run(input)` before calling `interp.summary()`."
  
      # Build up a list of summary information for each node
      node_summaries: List[List[Any]] = []
  
      def mem_repr(mem: int) -> str:
          unit_divisor_map = {
              "kb": 1024,
              "mb": 1024**2,
              "gb": 1024**3,
              "tb": 1024**4,
          }
          return f"{mem / unit_divisor_map[unit.lower()]:.2f} {unit.upper()}"
  
      def flops_repr(flop: int) -> str:
          return f"{flop:,} FLOPs"
  
      accumulate_size = 0
      for node in self.module.graph.nodes:
          node: Node
          accumulate_size += calculate_fwd_out(
              node
          ) + calculate_fwd_tmp(node)
          node_summaries.append(
              [
                  node.op,
                  str(node),
                  flops_repr(node.meta["fwd_flop"]),
                  flops_repr(node.meta["bwd_flop"]),
                  mem_repr(accumulate_size),
                  mem_repr(calculate_fwd_in(node)),
                  mem_repr(calculate_fwd_out(node)),
                  mem_repr(calculate_fwd_tmp(node)),
                  mem_repr(node.meta["bwd_mem_out"]),
                  mem_repr(node.meta["bwd_mem_tmp"]),
              ]
          )
  
      # Use the ``tabulate`` library to create a well-formatted table
      # presenting our summary information
      headers: List[str] = [
          "Op type",
          "Op",
          "Forward FLOPs",
          "Backward FLOPs",
          "Accumulated Memory",
          "FWD_IN",
          "FWD_OUT",
          "FWD_TMP",
          "BWD_OUT",
          "BWD_TMP",
      ]
  
      return tabulate(node_summaries, headers=headers, stralign="right")
  
imports: from dataclasses import asdict
  from typing import Any, Dict, List, NamedTuple, Tuple
  import torch
  import torch.fx
  from torch.fx.node import Argument, Node, Target
  from torch.utils._pytree import tree_map
  from colossalai.fx._compatibility import compatibility, is_compatible_with_meta
  from colossalai.fx.profiler import GraphInfo, activation_size, calculate_fwd_in, calculate_fwd_out, calculate_fwd_tmp, profile_function, profile_method, profile_module
label_desc: Use image node_id 9 for calling the MetaInfoProp obj's underlying member method code with example usage: obj.summary(unit) and returns: tabulate, unknown, str, unit, flop, str