code: def test_get_shared_rows(self) -> None:
      X1 = torch.rand(4, 2)
  
      # X1 is subset of X2
      X2 = torch.cat((X1[:2], torch.rand(1, 2), X1[2:]))
      X_shared, shared_idcs = _get_shared_rows([X1, X2])
      self.assertTrue(torch.equal(X1, X_shared))
      self.assertTrue(torch.equal(shared_idcs[0], torch.arange(4)))
      self.assertTrue(
          torch.equal(shared_idcs[1], torch.tensor([0, 1, 3, 4]))
      )
  
      # X2 is subset of X1
      X2 = X1[:3]
      X_shared, shared_idcs = _get_shared_rows([X1, X2])
      self.assertTrue(torch.equal(X2, X_shared))
      self.assertTrue(torch.equal(shared_idcs[0], torch.arange(3)))
      self.assertTrue(torch.equal(shared_idcs[1], torch.arange(3)))
  
      # no overlap
      X2 = torch.rand(2, 2)
      X_shared, shared_idcs = _get_shared_rows([X1, X2])
      self.assertEqual(X_shared.numel(), 0)
      self.assertEqual(shared_idcs[0].numel(), 0)
      self.assertEqual(shared_idcs[1].numel(), 0)
  
      # three tensors
      X2 = torch.cat((X1[:2], torch.rand(1, 2), X1[2:]))
      X3 = torch.cat(
          (torch.rand(1, 2), X1[:2], torch.rand(1, 2), X1[3:4])
      )
      X_shared, shared_idcs = _get_shared_rows([X1, X2, X3])
      self.assertTrue(
          torch.equal(shared_idcs[0], torch.tensor([0, 1, 3]))
      )
      self.assertTrue(
          torch.equal(shared_idcs[1], torch.tensor([0, 1, 4]))
      )
      self.assertTrue(
          torch.equal(shared_idcs[2], torch.tensor([1, 2, 4]))
      )
      self.assertTrue(
          torch.equal(X_shared, X1[torch.tensor([0, 1, 3])])
      )
  
imports: import warnings
  from typing import OrderedDict
  import numpy
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.exceptions.core import AxError, AxWarning, UnsupportedError
  from ax.models.torch.botorch_modular.utils import _get_shared_rows, _tensor_difference, check_metric_dataset_match, choose_botorch_acqf_class, choose_model_class, construct_acquisition_and_optimizer_options, convert_to_block_design, get_subset_datasets, subset_state_dict, use_model_list
  from ax.models.torch.utils import _to_inequality_constraints
  from ax.utils.common.constants import Keys
  from ax.utils.common.testutils import TestCase
  from ax.utils.common.typeutils import checked_cast, not_none
  from ax.utils.testing.torch_stubs import get_torch_test_data
  from botorch.acquisition import qLogNoisyExpectedImprovement
  from botorch.acquisition.multi_objective.logei import qLogNoisyExpectedHypervolumeImprovement
  from botorch.models.fully_bayesian import SaasFullyBayesianSingleTaskGP
  from botorch.models.gp_regression import SingleTaskGP
  from botorch.models.gp_regression_fidelity import SingleTaskMultiFidelityGP
  from botorch.models.gp_regression_mixed import MixedSingleTaskGP
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.models.multitask import MultiTaskGP
  from botorch.utils.datasets import SupervisedDataset
label_desc: Use image node_id 10 for calling the BoTorchModelUtilsTest obj's underlying member method code with example usage: obj.test_get_shared_rows() without return types