code: def test_prob(nderivs):
      #      +-------+
      #  z --|--> x  |
      #      +-------+
      num_particles = 10000
      data = torch.tensor([0.5, 1.0, 1.5])
      p = pyro.param("p", torch.tensor(0.25))
  
      @config_enumerate
      def model(num_particles):
          p = pyro.param("p")
          with pyro.plate("num_particles", num_particles, dim=-2):
              z = pyro.sample("z", dist.Bernoulli(p))
              with pyro.plate("data", 3):
                  pyro.sample("x", dist.Normal(z, 1.0), obs=data)
  
      def guide(num_particles):
          pass
  
      elbo = TraceEnum_ELBO(max_plate_nesting=2)
      expected_logprob = -elbo.differentiable_loss(
          model, guide, num_particles=1
      )
  
      posterior_model = infer_discrete(
          config_enumerate(model, "parallel"), first_available_dim=-3
      )
      posterior_trace = poutine.trace(posterior_model).get_trace(
          num_particles=num_particles
      )
      actual_logprob = log_mean_prob(posterior_trace, particle_dim=-2)
  
      if nderivs == 0:
          assert_equal(expected_logprob, actual_logprob, prec=1e-3)
      elif nderivs == 1:
          expected_grad = grad(expected_logprob, [p])[0]
          actual_grad = grad(actual_logprob, [p])[0]
          assert_equal(expected_grad, actual_grad, prec=1e-3)
  
imports: import logging
  import math
  import warnings
  import pytest
  import torch
  from torch.autograd import grad
  import pyro
  import pyro.distributions
  from pyro import poutine
  from pyro.infer import TraceEnum_ELBO
  from pyro.infer.discrete import TraceEnumSample_ELBO, infer_discrete
  from pyro.infer.enum import config_enumerate
  from tests.common import assert_equal
label_desc: Use image node_id 9 for calling a global function with example usage: test_prob(nderivs) without return types