code: def test_elbo_enumerate_plate_7(scale):
      #  Guide    Model
      #    a -----> b
      #    |        |
      #  +-|--------|----------------+
      #  | V        V                |
      #  | c -----> d -----> e   N=2 |
      #  +---------------------------+
      # This tests a mixture of model and guide enumeration.
      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]]),  # deterministic
          constraint=constraints.simplex,
      )
  
      @handlers.scale(scale=scale)
      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):
              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)
  
      @handlers.scale(scale=scale)
      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):
              pyro.sample("c", dist.Categorical(probs_c[a]))
  
      @handlers.scale(scale=scale)
      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 pyro.plate("data", 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],
              )
  
      @handlers.scale(scale=scale)
      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 pyro.plate("data", 2):
              pyro.sample(
                  "c_{}".format(i), dist.Categorical(probs_c[a])
              )
  
      data = torch.tensor([0, 0])
      elbo = infer.TraceEnum_ELBO(max_plate_nesting=1)
      auto_loss = elbo.differentiable_loss(auto_model, auto_guide, data)
      elbo = infer.TraceEnum_ELBO(max_plate_nesting=0)
      hand_loss = elbo.differentiable_loss(hand_model, hand_guide, data)
      _check_loss_and_grads(hand_loss, auto_loss)
  
imports: import logging
  import os
  import pyroapi
  import pytest
  import torch
  from torch.autograd import grad
  from torch.distributions import constraints
  from pyro.ops.indexing import Vindex
  from pyro.util import torch_isnan
  from tests.common import assert_equal, xfail_param
label_desc: Use image node_id 12 for calling a global function with example usage: test_elbo_enumerate_plate_7(scale) without return types