code: def get_fn_name(fn, show_attrs, max_attr_chars):
      name = str(type(fn).__name__)
      if not show_attrs:
          return name
      attrs = dict()
      for attr in dir(fn):
          if not attr.startswith(SAVED_PREFIX):
              continue
          val = getattr(fn, attr)
          attr = attr[len(SAVED_PREFIX) :]
          if torch.is_tensor(val):
              attrs[attr] = "[saved tensor]"
          elif isinstance(val, tuple) and any(
              torch.is_tensor(t) for t in val
          ):
              attrs[attr] = "[saved tensors]"
          else:
              attrs[attr] = str(val)
      if not attrs:
          return name
      max_attr_chars = max(max_attr_chars, 3)
      col1width = max(len(k) for k in attrs.keys())
      col2width = min(
          max(len(str(v)) for v in attrs.values()), max_attr_chars
      )
      sep = "-" * max(col1width + col2width + 2, len(name))
      attrstr = "%-" + str(col1width) + "s: %" + str(col2width) + "s"
      truncate = (
          lambda s: s[: col2width - 3] + "..."
          if len(s) > col2width
          else s
      )
      params = "\n".join(
          attrstr % (k, truncate(str(v))) for (k, v) in attrs.items()
      )
      return name + "\n" + sep + "\n" + params
  
file_path: pytorchviz/torchviz/dot.py
imports: from collections import namedtuple
  from distutils.version import LooseVersion
  from graphviz import Digraph
  import torch
  from torch.autograd import Variable
  import warnings
label_desc: Use image node_id 1 for calling a global function with example usage: get_fn_name(fn, show_attrs, max_attr_chars) and returns: unknown, name, name