    def shard_iterable(self, iterable: Iterable[_T]) -> Iterator[_T]:
        """
        Helper method that determines which items in an iterable object to skip based
        on the current node rank (for distributed training) and worker ID (for multi-process data loading).
        """
        if not self.manual_distributed_sharding or not self.manual_multiprocess_sharding:
            raise ValueError(
                "self.shard_iterable() was called but self.manual_distributed_sharding and "
                "self.manual_multiprocess_sharding was not set to True. Did you forget to call "
                "super().__init__(manual_distributed_sharding=True, manual_multiprocess_sharding=True) "
                "in your constructor?"
            )

        sharded_slice: Iterator[_T] = iter(iterable)

        if util.is_distributed():
            sharded_slice = itertools.islice(
                sharded_slice, dist.get_rank(), None, dist.get_world_size()
            )

        if self._worker_info is not None:
            sharded_slice = itertools.islice(
                sharded_slice, self._worker_info.id, None, self._worker_info.num_workers
            )

        # We don't know for sure how many instances we have to produce.
        # _multi_worker_islice() figures that out. But we know for sure
        # it won't be more than max_instances.
        if self.max_instances is not None:
            sharded_slice = itertools.islice(sharded_slice, self.max_instances)

        return sharded_slice
Helper method that determines which items in an iterable object to skip based
on the current node rank (for distributed training) and worker ID (for multi-process data loading).
allennlp/data/dataset_readers/dataset_reader.py