class_docstr: Execute an FX graph Node-by-Node and record a fake tensor representing
  the metadata for the node.  Unlike ShapeProp, (1) this propagation
  is cheap--it does the propagation with meta tensors which do not actually
  store data, and (2) the fake tensors have much more fine grained information,
  e.g., they have accurate alias information that can be consulted by looking
  at the storages.
  
  Args:
       module (GraphModule): The module to be executed
       mode (Optional[FakeTensorMode]): The dispatch mode used to execute computation indicated by each FX Node.
class_docstr_tok: ["Execute","an","FX","graph","Node-by-Node","and","record","a","fake","tensor","representing","the","metadata","for","the","node",".","Unlike","ShapeProp",",","(","1",")","this","propagation","is","cheap","--","it","does","the","propagation","with","meta","tensors","which","do","not","actually","store","data",",","and","(","2",")","the","fake","tensors","have","much","more","fine","grained","information",",","e.g.",",","they","have","accurate","alias","information","that","can","be","consulted","by","looking","at","the","storages",".","Args",":","module","(","GraphModule",")",":","The","module","to","be","executed","mode","(","Optional","[","FakeTensorMode","]",")",":","The","dispatch","mode","used","to","execute","computation","indicated","by","each","FX","Node","."]
code: def run_node(self, n: Node):
      import sympy
      from torch.fx.experimental.symbolic_shapes import (
          free_unbacked_symbols,
      )
  
      result = super().run_node(n)
      sym = None
      if (
          "val" in n.meta
          and isinstance(v := n.meta["val"], torch.SymInt)
          and isinstance(v.node.expr, sympy.Symbol)
          and free_unbacked_symbols(v)
      ):
          sym = v
  
      def extract_val(obj):
          if isinstance(obj, FakeTensor):
              return snapshot_fake(obj)
          elif isinstance(obj, torch.Tensor):
              # TODO: How is it possible that we get a non fake tensor?  We
              # should be running under the mode...
              return snapshot_fake(
                  self._mode.from_tensor(obj, static_shapes=True)
              )
          elif isinstance(obj, py_sym_types):
              return obj
          else:
              return None
  
      meta = map_aggregate(result, extract_val)
      if meta is not None:
          n.meta["val"] = meta
          if sym is not None:
              torch._check(meta == v)
      return result
  
file_path: pytorch/torch/fx/passes/fake_tensor_prop.py
imports: from typing import Optional
  import torch.fx
  from torch.fx import Node
  from torch.fx._compatibility import compatibility
  from torch._subclasses.fake_tensor import FakeTensorMode, FakeTensor
  from torch.fx.experimental.proxy_tensor import py_sym_types, snapshot_fake
  from torch.fx.node import map_aggregate
label_desc: Use image node_id 2 for calling the FakeTensorProp obj's underlying member method code with example usage: obj.run_node(n) and returns: result, snapshot_fake, snapshot_fake, obj, None