code: def test_torch_batch_follows_valid_max_batches(
      mock_synchronize_and_checkpoint: unittest.mock.MagicMock,
      mock_initialize_default_inference_context: unittest.mock.MagicMock,
      data_length: int,
      batch_size: int,
      checkpoint_interval: int,
      rank: int,
      num_slots: int,
      max_batches: int,
      expected_process_batch_call_count: int,
  ) -> None:
      with test_util.set_mock_cluster_info(
          DEFAULT_ADDRS, rank, num_slots
      ):
          mock_initialize_default_inference_context.return_value = (
              core._dummy_init(distributed=_get_dist_context(rank=rank))
          )
  
          index_dataset = IndexData(data_length)
  
          MyProcessorCLS = unittest.mock.Mock()
          my_processor_instance = unittest.mock.Mock()
          MyProcessorCLS.return_value = my_processor_instance
  
          experimental.torch_batch_process(
              dataset=index_dataset,
              batch_processor_cls=MyProcessorCLS,
              batch_size=batch_size,
              checkpoint_interval=checkpoint_interval,
              max_batches=max_batches,
          )
  
          assert (
              my_processor_instance.process_batch.call_count
              == expected_process_batch_call_count
          )
          # on_finish should only be called once
          assert my_processor_instance.on_finish.call_count == 1
  
imports: import math
  import unittest.mock
  from typing import Any, Dict, List, Optional
  import pytest
  import torch
  from torch.utils import data
  from determined import core, pytorch
  from determined.pytorch import experimental
  from tests.launch import test_util
label_desc: Use image node_id 8 for calling a global function with example usage: test_torch_batch_follows_valid_max_batches(mock_synchronize_and_checkpoint, mock_initialize_default_inference_context, data_length, batch_size, checkpoint_interval, rank, num_slots, max_batches, expected_process_batch_call_count) without return types