code: def test_elbo_enumerate_plates_8(
      model_scale, guide_scale, inner_vectorized, outer_vectorized
  ):
      #        Guide   Model
      #                  a
      #      +-----------|--------+
      #      | M=2   +---|------+ |
      #      |       |   V  N=2 | |
      #      |   b ----> c      | |
      #      |       +----------+ |
      #      +--------------------+
      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]),
          constraint=constraints.simplex,
      )
      pyro.param(
          "model_probs_c",
          torch.tensor(
              [
                  [[0.4, 0.5, 0.1], [0.3, 0.5, 0.2]],
                  [[0.3, 0.4, 0.3], [0.4, 0.4, 0.2]],
              ]
          ),
          constraint=constraints.simplex,
      )
      pyro.param(
          "guide_probs_b",
          torch.tensor([0.8, 0.2]),
          constraint=constraints.simplex,
      )
      data = torch.tensor([[0, 1], [0, 2]])
  
      @infer.config_enumerate
      @handlers.scale(scale=model_scale)
      def model_plate_plate():
          probs_a = pyro.param("model_probs_a")
          probs_b = pyro.param("model_probs_b")
          probs_c = pyro.param("model_probs_c")
          a = pyro.sample("a", dist.Categorical(probs_a))
          with pyro.plate("outer", 2):
              b = pyro.sample("b", dist.Categorical(probs_b))
              with pyro.plate("inner", 2):
                  pyro.sample(
                      "c",
                      dist.Categorical(Vindex(probs_c)[a, b]),
                      obs=data,
                  )
  
      @infer.config_enumerate
      @handlers.scale(scale=model_scale)
      def model_iplate_plate():
          probs_a = pyro.param("model_probs_a")
          probs_b = pyro.param("model_probs_b")
          probs_c = pyro.param("model_probs_c")
          inner = pyro.plate("inner", 2)
          a = pyro.sample("a", dist.Categorical(probs_a))
          for i in pyro.plate("outer", 2):
              b = pyro.sample(
                  "b_{}".format(i), dist.Categorical(probs_b)
              )
              with inner:
                  pyro.sample(
                      "c_{}".format(i),
                      dist.Categorical(Vindex(probs_c)[a, b]),
                      obs=data[:, i],
                  )
  
      @infer.config_enumerate
      @handlers.scale(scale=model_scale)
      def model_plate_iplate():
          probs_a = pyro.param("model_probs_a")
          probs_b = pyro.param("model_probs_b")
          probs_c = pyro.param("model_probs_c")
          a = pyro.sample("a", dist.Categorical(probs_a))
          with pyro.plate("outer", 2):
              b = pyro.sample("b", dist.Categorical(probs_b))
              for j in pyro.plate("inner", 2):
                  pyro.sample(
                      "c_{}".format(j),
                      dist.Categorical(Vindex(probs_c)[a, b]),
                      obs=data[j],
                  )
  
      @infer.config_enumerate
      @handlers.scale(scale=model_scale)
      def model_iplate_iplate():
          probs_a = pyro.param("model_probs_a")
          probs_b = pyro.param("model_probs_b")
          probs_c = pyro.param("model_probs_c")
          inner = pyro.plate("inner", 2)
          a = pyro.sample("a", dist.Categorical(probs_a))
          for i in pyro.plate("outer", 2):
              b = pyro.sample(
                  "b_{}".format(i), dist.Categorical(probs_b)
              )
              for j in inner:
                  pyro.sample(
                      "c_{}_{}".format(i, j),
                      dist.Categorical(Vindex(probs_c)[a, b]),
                      obs=data[j, i],
                  )
  
      @infer.config_enumerate
      @handlers.scale(scale=guide_scale)
      def guide_plate():
          probs_b = pyro.param("guide_probs_b")
          with pyro.plate("outer", 2):
              pyro.sample("b", dist.Categorical(probs_b))
  
      @infer.config_enumerate
      @handlers.scale(scale=guide_scale)
      def guide_iplate():
          probs_b = pyro.param("guide_probs_b")
          for i in pyro.plate("outer", 2):
              pyro.sample("b_{}".format(i), dist.Categorical(probs_b))
  
      elbo = infer.TraceEnum_ELBO(max_plate_nesting=0)
      expected_loss = elbo.differentiable_loss(
          model_iplate_iplate, guide_iplate
      )
      if inner_vectorized:
          if outer_vectorized:
              elbo = infer.TraceEnum_ELBO(max_plate_nesting=2)
              actual_loss = elbo.differentiable_loss(
                  model_plate_plate, guide_plate
              )
          else:
              elbo = infer.TraceEnum_ELBO(max_plate_nesting=1)
              actual_loss = elbo.differentiable_loss(
                  model_iplate_plate, guide_iplate
              )
      else:
          if outer_vectorized:
              elbo = infer.TraceEnum_ELBO(max_plate_nesting=1)
              actual_loss = elbo.differentiable_loss(
                  model_plate_iplate, guide_plate
              )
          else:
              elbo = infer.TraceEnum_ELBO(max_plate_nesting=1)
              actual_loss = elbo.differentiable_loss(
                  model_iplate_iplate, guide_iplate
              )
      _check_loss_and_grads(expected_loss, actual_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 20 for calling a global function with example usage: test_elbo_enumerate_plates_8(model_scale, guide_scale, inner_vectorized, outer_vectorized) without return types