class_docstr: Computes the log probability density of a trace (of a model with
  tree structure) that possibly contains discrete sample sites
  enumerated in parallel. This will be deprecated in favor of
  :class:`~pyro.infer.mcmc.util.EinsumTraceProbEvaluator`.
  
  :param model_trace: execution trace from a static model.
  :param bool has_enumerable_sites: whether the trace contains any
      discrete enumerable sites.
  :param int max_plate_nesting: Optional bound on max number of nested
      :func:`pyro.plate` contexts.
class_docstr_tok: ["Computes","the","log","probability","density","of","a","trace","(","of","a","model","with","tree","structure",")","that","possibly","contains","discrete","sample","sites","enumerated","in","parallel",".","This","will","be","deprecated","in","favor","of",":","class",":","`","~pyro.infer.mcmc.util.EinsumTraceProbEvaluator","`",".",":","param","model_trace",":","execution","trace","from","a","static","model",".",":","param","bool","has_enumerable_sites",":","whether","the","trace","contains","any","discrete","enumerable","sites",".",":","param","int","max_plate_nesting",":","Optional","bound","on","max","number","of","nested",":","func",":","`","pyro.plate","`","contexts","."]
code: def _parse_model_structure(self, model_trace):
      if not self.has_enumerable_sites:
          return
      if self.max_plate_nesting is None:
          raise ValueError(
              "Finite value required for `max_plate_nesting` when model "
              "has discrete (enumerable) sites."
          )
      self._compute_log_prob_terms(model_trace)
      # 1. Infer model structure - compute parent-child relationship.
      sorted_ordinals = sorted(self._log_probs.keys())
      for i, child_node in enumerate(sorted_ordinals):
          for j in range(i - 1, -1, -1):
              cur_node = sorted_ordinals[j]
              if cur_node < child_node:
                  self._children[cur_node].append(child_node)
                  break  # at most 1 parent.
      # 2. Populate `plate_dims` and `enum_dims` to be evaluated/
      #    enumerated out at each ordinal.
      self._populate_cache(frozenset(), frozenset(), set())
  
imports: import functools
  import traceback
  import warnings
  from collections import OrderedDict, defaultdict
  from functools import partial, reduce
  from itertools import product
  import torch
  from opt_einsum import shared_intermediates
  from torch.distributions import biject_to
  import pyro
  import pyro.poutine
  from pyro.distributions.util import broadcast_shape, logsumexp
  from pyro.infer import config_enumerate
  from pyro.infer.autoguide.initialization import InitMessenger, init_to_uniform
  from pyro.infer.util import is_validation_enabled
  from pyro.ops import stats
  from pyro.ops.contract import contract_to_tensor
  from pyro.ops.integrator import potential_grad
  from pyro.poutine.subsample_messenger import _Subsample
  from pyro.poutine.util import prune_subsample_sites
  from pyro.util import check_site_shape, ignore_jit_warnings
label_desc: Use image node_id 2 for calling the TraceTreeEvaluator obj's underlying member method code with example usage: obj._parse_model_structure(model_trace) without return types