code: def test_get_shard_range(self):
      # first 5 ranks should take 3 examples
      # last 3 ranks should take 2 examples, but to make sure all shard have
      # same size, we pad with the previous example.
      dataset_size, world_size = 21, 8
      expected = [
          (0, (0, 2)),
          (1, (3, 5)),
          (2, (6, 8)),
          (3, (9, 11)),
          (4, (12, 14)),
          (5, (14, 16)),
          (6, (16, 18)),
          (7, (18, 20)),
      ]
      for rank, expected_range in expected:
          shard_range = get_shard_range(dataset_size, rank, world_size)
          self.assertEqual(shard_range, expected_range)
  
      dataset_size, world_size = 16, 4
      expected = [(0, (0, 3)), (1, (4, 7)), (2, (8, 11)), (3, (12, 15))]
      for rank, expected_range in expected:
          shard_range = get_shard_range(dataset_size, rank, world_size)
          self.assertEqual(shard_range, expected_range)
  
imports: import json
  import os
  import random
  import shutil
  import tempfile
  import unittest
  import numpy
  import torch
  from pytext.utils import recursive_map, round_seq, set_random_seeds
  from pytext.utils.data import align_slot_labels, merge_token_labels_to_slot, strip_bio_prefix, unkify
  from pytext.utils.distributed import get_shard_range
  from pytext.utils.file_io import chunk_file, PathManager
  from pytext.utils.meter import TimeMeter
  from pytext.utils.test import import_tests_module
label_desc: Use image node_id 5 for calling the UtilTest obj's underlying member method code with example usage: obj.test_get_shard_range() without return types