class_docstr: Graph data structure denoting the relationships amongst different pyro primitives
  in the execution trace.
  
  An execution trace of a Pyro program is a record of every call
  to ``pyro.sample()`` and ``pyro.param()`` in a single execution of that program.
  Traces are directed graphs whose nodes represent primitive calls or input/output,
  and whose edges represent conditional dependence relationships
  between those primitive calls. They are created and populated by ``poutine.trace``.
  
  Each node (or site) in a trace contains the name, input and output value of the site,
  as well as additional metadata added by inference algorithms or user annotation.
  In the case of ``pyro.sample``, the trace also includes the stochastic function
  at the site, and any observed data added by users.
  
  Consider the following Pyro program:
  
      >>> def model(x):
      ...     s = pyro.param("s", torch.tensor(0.5))
      ...     z = pyro.sample("z", dist.Normal(x, s))
      ...     return z ** 2
  
  We can record its execution using ``pyro.poutine.trace``
  and use the resulting data structure to compute the log-joint probability
  of all of the sample sites in the execution or extract all parameters.
  
      >>> trace = pyro.poutine.trace(model).get_trace(0.0)
      >>> logp = trace.log_prob_sum()
      >>> params = [trace.nodes[name]["value"].unconstrained() for name in trace.param_nodes]
  
  We can also inspect or manipulate individual nodes in the trace.
  ``trace.nodes`` contains a ``collections.OrderedDict``
  of site names and metadata corresponding to ``x``, ``s``, ``z``, and the return value:
  
      >>> list(name for name in trace.nodes.keys())  # doctest: +SKIP
      ["_INPUT", "s", "z", "_RETURN"]
  
  Values of ``trace.nodes`` are dictionaries of node metadata:
  
      >>> trace.nodes["z"]  # doctest: +SKIP
      {'type': 'sample', 'name': 'z', 'is_observed': False,
       'fn': Normal(), 'value': tensor(0.6480), 'args': (), 'kwargs': {},
       'infer': {}, 'scale': 1.0, 'cond_indep_stack': (),
       'done': True, 'stop': False, 'continuation': None}
  
  ``'infer'`` is a dictionary of user- or algorithm-specified metadata.
  ``'args'`` and ``'kwargs'`` are the arguments passed via ``pyro.sample``
  to ``fn.__call__`` or ``fn.log_prob``.
  ``'scale'`` is used to scale the log-probability of the site when computing the log-joint.
  ``'cond_indep_stack'`` contains data structures corresponding to ``pyro.plate`` contexts
  appearing in the execution.
  ``'done'``, ``'stop'``, and ``'continuation'`` are only used by Pyro's internals.
  
  :param string graph_type: string specifying the kind of trace graph to construct
code: def __len__(self) -> int:
      return len(self.nodes)
  
imports: import sys
  from collections import OrderedDict
  from typing import TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, List, Literal, Optional, Set, Tuple, Union
  import opt_einsum
  from pyro.distributions.score_parts import ScoreParts
  from pyro.distributions.util import scale_and_mask
  from pyro.ops.packed import pack
  from pyro.poutine.util import is_validation_enabled
  from pyro.util import warn_if_inf, warn_if_nan
label_desc: Use image node_id 4 for calling the Trace obj's underlying member method code with example usage: obj.__len__() and returns: len