class_docstr: An implementation of the DiCE operator compatible with Pyro features.
  
  This implementation correctly handles:
  - scaled log-probability due to subsampling
  - independence in different ordinals due to plate
  - weights due to parallel and sequential enumeration
  - weights due to local multiple sampling
  
  This assumes restricted dependency structure on the model and guide:
  variables outside of an :class:`~pyro.plate` can never depend on
  variables inside that :class:`~pyro.plate`.
  
  References:
  [1] Jakob Foerster, Greg Farquhar, Maruan Al-Shedivat, Tim Rocktaeschel,
      Eric P. Xing, Shimon Whiteson (2018)
      "DiCE: The Infinitely Differentiable Monte-Carlo Estimator"
      https://arxiv.org/abs/1802.05098
  [2] Laurence Aitchison (2018)
      "Tensor Monte Carlo: particle methods for the GPU era"
      https://arxiv.org/abs/1806.08593
  
  :param pyro.poutine.trace.Trace guide_trace: A guide trace.
  :param ordering: A dictionary mapping model site names to ordinal values.
      Ordinal values may be any type that is (1) ``<=`` comparable and (2)
      hashable; the canonical ordinal is a ``frozenset`` of site names.
code: def __init__(self, guide_trace, ordering):
      log_denoms = defaultdict(
          float
      )  # avoids double-counting when sequentially enumerating
      log_probs = defaultdict(
          list
      )  # accounts for upstream probabilties
  
      for name, site in guide_trace.nodes.items():
          if site["type"] != "sample":
              continue
  
          ordinal = ordering[name]
          log_prob, log_denom = compute_site_dice_factor(site)
          if not is_identically_zero(log_prob):
              log_probs[ordinal].append(log_prob)
          if not is_identically_zero(log_denom):
              log_denoms[ordinal] += log_denom
  
      self.log_denom = log_denoms
      self.log_probs = log_probs
  
imports: import math
  import numbers
  from collections import Counter, defaultdict
  from contextlib import contextmanager
  import torch
  from opt_einsum import shared_intermediates
  from opt_einsum.sharing import count_cached_ops
  from pyro.distributions.util import is_identically_zero
  from pyro.ops import packed
  from pyro.ops.einsum.adjoint import require_backward
  from pyro.ops.rings import MarginalRing
  from pyro.poutine.util import site_is_subsample
  from ..None import settings
label_desc: Use image node_id 1 to create a new Dice object  with example: obj = Dice(guide_trace, ordering)