class_docstr: NodePathTracer is an FX tracer that, for each operation, also records the
  name of the Node from which the operation originated. A node name here is
  a `.` separated path walking the hierarchy from top level module down to
  leaf operation or leaf module. The name of the top level module is not
  included as part of the node name. For example, if we trace a module whose
  forward method applies a ReLU module, the name for that node will simply
  be 'relu'.
  
  Some notes on the specifics:
      - Nodes are recorded to `self.node_to_qualname` which is a dictionary
        mapping a given Node object to its node name.
      - Nodes are recorded in the order which they are executed during
        tracing.
      - When a duplicate node name is encountered, a suffix of the form
        _{int} is added. The counter starts from 1.
code: def _get_node_qualname(
      self, module_qualname: str, node: fx.node.Node
  ) -> str:
      node_qualname = module_qualname
  
      if node.op != "call_module":
          # In this case module_qualname from torch.fx doesn't go all the
          # way to the leaf function/op, so we need to append it
          if len(node_qualname) > 0:
              # Only append '.' if we are deeper than the top level module
              node_qualname += "."
          node_qualname += str(node)
  
      # Now we need to add an _{index} postfix on any repeated node names
      # For modules we do this from scratch
      # But for anything else, torch.fx already has a globally scoped
      # _{index} postfix. But we want it locally (relative to direct parent)
      # scoped. So first we need to undo the torch.fx postfix
      if re.match(r".+_[0-9]+$", node_qualname) is not None:
          node_qualname = node_qualname.rsplit("_", 1)[0]
  
      # ... and now we add on our own postfix
      for existing_qualname in reversed(self.node_to_qualname.values()):
          # Check to see if existing_qualname is of the form
          # {node_qualname} or {node_qualname}_{int}
          if (
              re.match(
                  rf"{node_qualname}(_[0-9]+)?$", existing_qualname
              )
              is not None
          ):
              postfix = existing_qualname.replace(node_qualname, "")
              if len(postfix):
                  # existing_qualname is of the form {node_qualname}_{int}
                  next_index = int(postfix[1:]) + 1
              else:
                  # existing_qualname is of the form {node_qualname}
                  next_index = 1
              node_qualname += f"_{next_index}"
              break
  
      return node_qualname
  
imports: import inspect
  import math
  import re
  import warnings
  from collections import OrderedDict
  from copy import deepcopy
  from itertools import chain
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import torch
  import torchvision
  from torch import fx, nn
  from torch.fx.graph_module import _copy_attr
label_desc: Use image node_id 4 for calling the NodePathTracer obj's underlying member method code with example usage: obj._get_node_qualname(module_qualname, node) and returns: node_qualname