code: def test_subsample_gradient(
      Elbo,
      reparameterized,
      has_rsample,
      subsample,
      local_samples,
      scale,
  ):
      pyro.clear_param_store()
      data = torch.tensor([-0.5, 2.0])
      subsample_size = 1 if subsample else len(data)
      precision = 0.06 * scale
      Normal = (
          dist.Normal
          if reparameterized
          else fakes.NonreparameterizedNormal
      )
  
      def model(subsample):
          with pyro.plate(
              "data", len(data), subsample_size, subsample
          ) as ind:
              x = data[ind]
              z = pyro.sample("z", Normal(0, 1))
              pyro.sample("x", Normal(z, 1), obs=x)
  
      def guide(subsample):
          scale = pyro.param("scale", lambda: torch.tensor([1.0]))
          with pyro.plate("data", len(data), subsample_size, subsample):
              loc = pyro.param(
                  "loc", lambda: torch.zeros(len(data)), event_dim=0
              )
              z_dist = Normal(loc, scale)
              if has_rsample is not None:
                  z_dist.has_rsample_(has_rsample)
              pyro.sample("z", z_dist)
  
      if scale != 1.0:
          model = poutine.scale(model, scale=scale)
          guide = poutine.scale(guide, scale=scale)
  
      num_particles = 50000
      if local_samples:
          guide = config_enumerate(guide, num_samples=num_particles)
          num_particles = 1
  
      optim = Adam({"lr": 0.1})
      elbo = Elbo(
          max_plate_nesting=1,  # set this to ensure rng agrees across runs
          num_particles=num_particles,
          vectorize_particles=True,
          strict_enumeration_warning=False,
      )
      inference = SVI(model, guide, optim, loss=elbo)
      with xfail_if_not_implemented():
          if subsample_size == 1:
              inference.loss_and_grads(
                  model,
                  guide,
                  subsample=torch.tensor([0], dtype=torch.long),
              )
              inference.loss_and_grads(
                  model,
                  guide,
                  subsample=torch.tensor([1], dtype=torch.long),
              )
          else:
              inference.loss_and_grads(
                  model,
                  guide,
                  subsample=torch.tensor([0, 1], dtype=torch.long),
              )
      params = dict(pyro.get_param_store().named_parameters())
      normalizer = 2 if subsample else 1
      actual_grads = {
          name: param.grad.detach().cpu().numpy() / normalizer
          for name, param in params.items()
      }
  
      expected_grads = {
          "loc": scale * np.array([0.5, -2.0]),
          "scale": scale * np.array([2.0]),
      }
      for name in sorted(params):
          logger.info(
              "expected {} = {}".format(name, expected_grads[name])
          )
          logger.info(
              "actual   {} = {}".format(name, actual_grads[name])
          )
      assert_equal(actual_grads, expected_grads, prec=precision)
  
file_path: pyro/tests/infer/test_gradient.py
imports: import logging
  import numpy
  import pytest
  import torch
  import torch.optim
  from torch.distributions import constraints
  import pyro
  import pyro.distributions
  import pyro.poutine
  from pyro.distributions.testing import fakes
  from pyro.infer import SVI, JitTrace_ELBO, JitTraceEnum_ELBO, JitTraceGraph_ELBO, JitTraceMeanField_ELBO, Trace_ELBO, TraceEnum_ELBO, TraceGraph_ELBO, TraceMeanField_ELBO, config_enumerate
  from pyro.optim import Adam
  from tests.common import assert_equal, xfail_if_not_implemented, xfail_param
label_desc: Use image node_id 3 for calling a global function with example usage: test_subsample_gradient(Elbo, reparameterized, has_rsample, subsample, local_samples, scale) without return types