code: def test_sequential_gamma_gaussian_tensordot(
      batch_shape, state_dim, num_steps
  ):
      g = random_gamma_gaussian(
          batch_shape + (num_steps,), state_dim + state_dim
      )
      actual = _sequential_gamma_gaussian_tensordot(g)
      assert actual.dim() == g.dim()
      assert actual.batch_shape == batch_shape
  
      # Check against hand computation.
      expected = g[..., 0]
      for t in range(1, num_steps):
          expected = gamma_gaussian_tensordot(
              expected, g[..., t], state_dim
          )
      assert_close_gamma_gaussian(actual, expected)
  
imports: import logging
  import operator
  from functools import reduce
  import opt_einsum
  import pytest
  import torch
  import pyro
  import pyro.distributions
  from pyro.distributions.hmm import _sequential_gamma_gaussian_tensordot, _sequential_logmatmulexp
  from pyro.distributions.util import broadcast_shape
  from pyro.infer import TraceEnum_ELBO, config_enumerate
  from pyro.ops.gamma_gaussian import gamma_and_mvn_to_gamma_gaussian, gamma_gaussian_tensordot, matrix_and_mvn_to_gamma_gaussian
  from pyro.ops.gaussian import gaussian_tensordot, matrix_and_mvn_to_gaussian, mvn_to_gaussian
  from pyro.ops.indexing import Vindex
  from tests.common import assert_close
  from tests.ops.gamma_gaussian import assert_close_gamma_gaussian, random_gamma, random_gamma_gaussian
  from tests.ops.gaussian import random_mvn
label_desc: Use image node_id 4 for calling a global function with example usage: test_sequential_gamma_gaussian_tensordot(batch_shape, state_dim, num_steps) without return types