code: def test_elbo_enumerate_plate_7(backend):
      #  Guide    Model
      #    a -----> b
      #    |        |
      #  +-|--------|----------------+
      #  | V        V                |
      #  | c -----> d -----> e   N=2 |
      #  +---------------------------+
      # This tests a mixture of model and guide enumeration.
      with pyro_backend(backend):
          pyro.param(
              "model_probs_a",
              torch.tensor([0.45, 0.55]),
              constraint=constraints.simplex,
          )
          pyro.param(
              "model_probs_b",
              torch.tensor([[0.6, 0.4], [0.4, 0.6]]),
              constraint=constraints.simplex,
          )
          pyro.param(
              "model_probs_c",
              torch.tensor([[0.75, 0.25], [0.55, 0.45]]),
              constraint=constraints.simplex,
          )
          pyro.param(
              "model_probs_d",
              torch.tensor(
                  [[[0.4, 0.6], [0.3, 0.7]], [[0.3, 0.7], [0.2, 0.8]]]
              ),
              constraint=constraints.simplex,
          )
          pyro.param(
              "model_probs_e",
              torch.tensor([[0.75, 0.25], [0.55, 0.45]]),
              constraint=constraints.simplex,
          )
          pyro.param(
              "guide_probs_a",
              torch.tensor([0.35, 0.64]),
              constraint=constraints.simplex,
          )
          pyro.param(
              "guide_probs_c",
              torch.tensor([[0.0, 1.0], [1.0, 0.0]]),
              constraint=constraints.simplex,
          )  # deterministic
  
          def auto_model(data):
              probs_a = pyro.param("model_probs_a")
              probs_b = pyro.param("model_probs_b")
              probs_c = pyro.param("model_probs_c")
              probs_d = pyro.param("model_probs_d")
              probs_e = pyro.param("model_probs_e")
              a = pyro.sample("a", dist.Categorical(probs_a))
              b = pyro.sample(
                  "b",
                  dist.Categorical(probs_b[a]),
                  infer={"enumerate": "parallel"},
              )
              with pyro.plate("data", 2, dim=-1):
                  c = pyro.sample("c", dist.Categorical(probs_c[a]))
                  d = pyro.sample(
                      "d",
                      dist.Categorical(Vindex(probs_d)[b, c]),
                      infer={"enumerate": "parallel"},
                  )
                  pyro.sample(
                      "obs", dist.Categorical(probs_e[d]), obs=data
                  )
  
          def auto_guide(data):
              probs_a = pyro.param("guide_probs_a")
              probs_c = pyro.param("guide_probs_c")
              a = pyro.sample(
                  "a",
                  dist.Categorical(probs_a),
                  infer={"enumerate": "parallel"},
              )
              with pyro.plate("data", 2, dim=-1):
                  pyro.sample("c", dist.Categorical(probs_c[a]))
  
          def hand_model(data):
              probs_a = pyro.param("model_probs_a")
              probs_b = pyro.param("model_probs_b")
              probs_c = pyro.param("model_probs_c")
              probs_d = pyro.param("model_probs_d")
              probs_e = pyro.param("model_probs_e")
              a = pyro.sample("a", dist.Categorical(probs_a))
              b = pyro.sample(
                  "b",
                  dist.Categorical(probs_b[a]),
                  infer={"enumerate": "parallel"},
              )
              for i in range(2):
                  c = pyro.sample(
                      "c_{}".format(i), dist.Categorical(probs_c[a])
                  )
                  d = pyro.sample(
                      "d_{}".format(i),
                      dist.Categorical(Vindex(probs_d)[b, c]),
                      infer={"enumerate": "parallel"},
                  )
                  pyro.sample(
                      "obs_{}".format(i),
                      dist.Categorical(probs_e[d]),
                      obs=data[i],
                  )
  
          def hand_guide(data):
              probs_a = pyro.param("guide_probs_a")
              probs_c = pyro.param("guide_probs_c")
              a = pyro.sample(
                  "a",
                  dist.Categorical(probs_a),
                  infer={"enumerate": "parallel"},
              )
              for i in range(2):
                  pyro.sample(
                      "c_{}".format(i), dist.Categorical(probs_c[a])
                  )
  
          data = torch.tensor([0, 0])
          elbo = infer.TraceEnum_ELBO(max_plate_nesting=1)
          elbo = elbo.differentiable_loss if backend == "pyro" else elbo
          auto_loss = elbo(auto_model, auto_guide, data)
          elbo = infer.TraceEnum_ELBO(max_plate_nesting=0)
          elbo = elbo.differentiable_loss if backend == "pyro" else elbo
          hand_loss = elbo(hand_model, hand_guide, data)
          _check_loss_and_grads(
              hand_loss, auto_loss, rtol=1e-3, atol=1e-3
          )
  
imports: import warnings
  import pytest
  import funsor
  from funsor.testing import xfail_param
  from funsor.util import get_backend
label_desc: Use image node_id 20 for calling a global function with example usage: test_elbo_enumerate_plate_7(backend) without return types