code: def test_gather(self, device, dtype):
      m, n, o = (
          random.randint(10, 20),
          random.randint(10, 20),
          random.randint(10, 20),
      )
      elems_per_row = random.randint(1, 10)
      dim = random.randrange(3)
  
      src = make_tensor((m, n, o), device=device, dtype=dtype)
      idx_size = [m, n, o]
      idx_size[dim] = elems_per_row
      idx = make_tensor(idx_size, device=device, dtype=torch.long)
      self._fill_indices(
          idx, dim, src.size(dim), elems_per_row, m, n, o
      )
  
      actual = torch.gather(src, dim, idx)
      expected = torch.zeros(idx_size, device=device, dtype=dtype)
      for i in range(idx_size[0]):
          for j in range(idx_size[1]):
              for k in range(idx_size[2]):
                  ii = [i, j, k]
                  ii[dim] = idx[i, j, k]
                  expected[i, j, k] = src[tuple(ii)]
      self.assertEqual(actual, expected, atol=0, rtol=0)
  
      # Guarded because torch.max isn't defined for complex types
      if not dtype.is_complex:
          src = make_tensor((3, 4, 5), device=device, dtype=dtype)
          expected, idx = src.max(2, True)
          actual = torch.gather(src, 2, idx)
          self.assertEqual(actual, expected, atol=0, rtol=0)
  
imports: import random
  import torch
  from torch.testing import make_tensor
  from torch.testing._internal.common_utils import parametrize, run_tests, TestCase, DeterministicGuard
  from torch.testing._internal.common_device_type import instantiate_device_type_tests, onlyCPU, dtypes, dtypesIfCUDA, toleranceOverride, tol
  from torch.testing._internal.common_dtype import get_all_dtypes
label_desc: Use image node_id 2 for calling the TestScatterGather obj's underlying member method code with example usage: obj.test_gather(device, dtype) without return types