code: def test_batch_matmul(self, use_keops=True, **kwargs):
      max_cholesky_size = (
          CHOLESKY_SIZE_KEOPS if use_keops else CHOLESKY_SIZE_NONKEOPS
      )
      with gpytorch.settings.max_cholesky_size(max_cholesky_size):
          x1 = torch.randn(3, 2, 100, 3)
          kern1 = self.k1(**kwargs)
          kern2 = self.k2(**kwargs)
  
          rhs = torch.randn(3, 2, 100, 1)
          with patch(
              "gpytorch.kernels.keops.keops_kernel.LazyTensor",
              wraps=lambda x: x,
          ) as keops_mock:
              # The patch makes sure that we're actually using KeOps
              res1 = kern1(x1, x1).matmul(rhs)
              res2 = kern2(x1, x1).matmul(rhs)
              self.assertLess(torch.norm(res1 - res2), 1e-4)
  
      if use_keops:
          self.assertTrue(keops_mock.called)
  
imports: from abc import abstractmethod
  from unittest.mock import patch
  import torch
  import gpytorch
  from .base_test_case import BaseTestCase
label_desc: Use image node_id 7 for calling the BaseKeOpsTestCase obj's underlying member method code with example usage: obj.test_batch_matmul(use_keops) without return types