import random
import unittest

from torch.utils.data import BatchSampler, DataLoader, IterableDataset

from accelerate import Accelerator
from accelerate.data_loader import (
    BatchSamplerShard,
    DataLoaderDispatcher,
    DataLoaderShard,
    IterableDatasetShard,
    SkipBatchSampler,
    SkipDataLoader,
    skip_first_batches,
)




class 	__A				(			a__     ):



    def __init__(self   :   Union[str, Any]       ,      __a   :   Any=0.01       ,      __a   :   List[str]=1000			):
         UpperCAmelCase_	   =       p_stop
         UpperCAmelCase_	   =       max_length






    def __iter__(self   :   Optional[Any]			):
         UpperCAmelCase_	   =       0
         UpperCAmelCase_	   =       False
         while not stop and count < self.max_length:
              yield count
              count += 1
              UpperCAmelCase_	   =       random.random() < self.p_stop




class 	__A				(			unittest.TestCase     ):



    def  _lowercase						(self   :   List[str]       ,      __a   :   int       ,      __a   :   int       ,      __a   :   str=False       ,      __a   :   List[Any]=True			):
         UpperCAmelCase_	   =       [
             BatchSamplerShard(_lowerCamelCase       ,      2       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)
             for i in range(2			)
         ]
         UpperCAmelCase_	   =       [list(_lowerCamelCase			) for batch_sampler_shard in batch_sampler_shards]
         if not split_batches:
              self.assertListEqual([len(_lowerCamelCase			) for shard in batch_sampler_shards]       ,      [len(_lowerCamelCase			) for e in expected]			)
         self.assertListEqual(_lowerCamelCase       ,      _lowerCamelCase			)



    def  _lowercase						(self   :   List[str]			):
         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [21, 22, 23]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         # Expected shouldn't change
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         # Check the shards when the dataset is a round multiple of batch size but not total batch size.
         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [0, 1, 2]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size but has a multiple of
         # num_processes batch.
         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [21, 0, 1]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size but and has not a multiple of
         # num_processes batch.
         UpperCAmelCase_	   =       BatchSampler(range(20			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 0]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [1, 2, 3]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(20			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         # Check the shards when the dataset is very small.
         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[[0, 1, 0]], [[1, 0, 1]]]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase			)



    def  _lowercase						(self   :   str			):
         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20, 21]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19], [22, 23]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         # Expected shouldn't change
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size.
         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20, 21]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19], [0, 1]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size or num_processes.
         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20, 0]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19], [1, 2]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         # Check the shards when the dataset is very small.
         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[[0, 1]], [[0, 1]]]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase			)



    def  _lowercase						(self   :   Optional[int]			):
         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [21, 22, 23]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         # Expected shouldn't change
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is a round multiple of batch size but not total batch size.
         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size but has a multiple of
         # num_processes batch.
         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19, 20]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17], [21]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size but and has not a multiple of
         # num_processes batch.
         UpperCAmelCase_	   =       BatchSampler(range(20			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14], [18, 19]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(20			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
             [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is very small.
         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[[0, 1]], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=3       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			)



    def  _lowercase						(self   :   Dict			):
         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20, 21]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19], [22, 23]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(24			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         # Expected shouldn't change
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size.
         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20, 21]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(22			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is not a round multiple of batch size or num_processes.
         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17], [20]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(21			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [
             [[0, 1], [4, 5], [8, 9], [12, 13], [16, 17]],
             [[2, 3], [6, 7], [10, 11], [14, 15], [18, 19]],
         ]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         # Check the shards when the dataset is very small.
         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[[0, 1]], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)

         UpperCAmelCase_	   =       BatchSampler(range(2			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       [[], []]
         self.check_batch_sampler_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      even_batches=_lowerCamelCase			)



    def  _lowercase						(self   :   Tuple			):
         UpperCAmelCase_	   =       [[0, 1, 2], [3, 4], [5, 6, 7, 8], [9, 10, 11], [12, 13]]
         UpperCAmelCase_	   =       [BatchSamplerShard(_lowerCamelCase       ,      2       ,      _lowerCamelCase       ,      even_batches=_lowerCamelCase			) for i in range(2			)]

         self.assertEqual(len(batch_sampler_shards[0]			)       ,      3			)
         self.assertEqual(len(batch_sampler_shards[1]			)       ,      2			)

         self.assertListEqual(list(batch_sampler_shards[0]			)       ,      [[0, 1, 2], [5, 6, 7, 8], [12, 13]]			)
         self.assertListEqual(list(batch_sampler_shards[1]			)       ,      [[3, 4], [9, 10, 11]]			)



    def  _lowercase						(self   :   List[str]       ,      __a   :   Optional[int]       ,      __a   :   Any       ,      __a   :   List[str]       ,      __a   :   Any=False       ,      __a   :   int=2       ,      __a   :   Union[str, Any]=False			):
         random.seed(_lowerCamelCase			)
         UpperCAmelCase_	   =       list(_lowerCamelCase			)

         UpperCAmelCase_	   =       [
             IterableDatasetShard(
                 _lowerCamelCase       ,      batch_size=_lowerCamelCase       ,      drop_last=_lowerCamelCase       ,      num_processes=_lowerCamelCase       ,      process_index=_lowerCamelCase       ,      split_batches=_lowerCamelCase       ,      )
             for i in range(_lowerCamelCase			)
         ]
         UpperCAmelCase_	   =       []
         for iterable_dataset_shard in iterable_dataset_shards:
              # Since our random iterable dataset will be... random... we need to use a seed to get reproducible results.
              random.seed(_lowerCamelCase			)
              iterable_dataset_lists.append(list(_lowerCamelCase			)			)

         UpperCAmelCase_	   =       batch_size // num_processes if split_batches else batch_size
         # All iterable dataset shard should have the same length, a round multiple of shard_batch_size
         UpperCAmelCase_	   =       iterable_dataset_lists[0]
         for l in iterable_dataset_lists[1:]:
              self.assertEqual(len(_lowerCamelCase			)       ,      len(_lowerCamelCase			)			)
              self.assertTrue(len(_lowerCamelCase			) % shard_batch_size == 0			)

         UpperCAmelCase_	   =       []
         for idx in range(0       ,      len(_lowerCamelCase			)       ,      _lowerCamelCase			):
              for l in iterable_dataset_lists:
                   observed += l[idx : idx + shard_batch_size]

         if not drop_last:
              while len(_lowerCamelCase			) < len(_lowerCamelCase			):
                   reference += reference
         self.assertListEqual(_lowerCamelCase       ,      reference[: len(_lowerCamelCase			)]			)



    def  _lowercase						(self   :   Optional[int]			):
         UpperCAmelCase_	   =       42
         UpperCAmelCase_	   =       RandomIterableDataset()

         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)

         # Edge case with a very small dataset
         UpperCAmelCase_	   =       RandomIterableDataset(max_length=2			)

         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)
         self.check_iterable_dataset_shards(_lowerCamelCase       ,      _lowerCamelCase       ,      batch_size=4       ,      drop_last=_lowerCamelCase       ,      split_batches=_lowerCamelCase			)



    def  _lowercase						(self   :   List[str]			):
         UpperCAmelCase_	   =       BatchSampler(range(16			)       ,      batch_size=4       ,      drop_last=_lowerCamelCase			)
         UpperCAmelCase_	   =       SkipBatchSampler(_lowerCamelCase       ,      2			)
         self.assertListEqual(list(_lowerCamelCase			)       ,      [[8, 9, 10, 11], [12, 13, 14, 15]]			)



    def  _lowercase						(self   :   List[Any]			):
         UpperCAmelCase_	   =       SkipDataLoader(list(range(16			)			)       ,      batch_size=4       ,      skip_batches=2			)
         self.assertListEqual([t.tolist() for t in dataloader]       ,      [[8, 9, 10, 11], [12, 13, 14, 15]]			)



    def  _lowercase						(self   :   List[Any]			):
         UpperCAmelCase_	   =       DataLoader(list(range(16			)			)       ,      batch_size=4			)
         UpperCAmelCase_	   =       skip_first_batches(_lowerCamelCase       ,      num_batches=2			)
         self.assertListEqual([t.tolist() for t in new_dataloader]       ,      [[8, 9, 10, 11], [12, 13, 14, 15]]			)



    def  _lowercase						(self   :   Optional[int]			):
         UpperCAmelCase_	   =       DataLoaderShard(list(range(16			)			)       ,      batch_size=4			)
         for idx, _ in enumerate(_lowerCamelCase			):
              self.assertEqual(dataloader.end_of_dataloader       ,      idx == 3			)

         # Test it also works on the second iteration
         for idx, _ in enumerate(_lowerCamelCase			):
              self.assertEqual(dataloader.end_of_dataloader       ,      idx == 3			)






    def  _lowercase						(self   :   Tuple			):
         Accelerator()
         UpperCAmelCase_	   =       DataLoaderDispatcher(range(16			)       ,      batch_size=4			)
         for idx, _ in enumerate(_lowerCamelCase			):
              self.assertEqual(dataloader.end_of_dataloader       ,      idx == 3			)

         # Test it also works on the second iteration
         for idx, _ in enumerate(_lowerCamelCase			):
              self.assertEqual(dataloader.end_of_dataloader       ,      idx == 3			)





'''simple docstring'''





from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


SCREAMING_SNAKE_CASE_:					Dict  =logging.get_logger(__name__)




class 	__A				(			UpperCamelCase__     ):



    def  _lowercase						(self   :   Dict       ,      __a   :   Any			):
         if isinstance(__a       ,      __a			):
              UpperCAmelCase_	   =       [label.strip() for label in labels.split(","			) if label.strip()]
         return labels






    def __call__(self   :   Union[str, Any]       ,      __a   :   Optional[int]       ,      __a   :   Optional[int]       ,      __a   :   int			):
         if len(__a			) == 0 or len(__a			) == 0:
              raise ValueError("You must include at least one label and at least one sequence."			)
         if hypothesis_template.format(labels[0]			) == hypothesis_template:
              raise ValueError(
                  (
                      "The provided hypothesis_template \"{}\" was not able to be formatted with the target labels. "
                      "Make sure the passed template includes formatting syntax such as {{}} where the label should go."
                  ).format(__a			)			)

         if isinstance(__a       ,      __a			):
              UpperCAmelCase_	   =       [sequences]

         UpperCAmelCase_	   =       []
         for sequence in sequences:
              sequence_pairs.extend([[sequence, hypothesis_template.format(__a			)] for label in labels]			)

         return sequence_pairs, sequences




@add_end_docstrings(UpperCamelCase__     )
class 	__A				(			UpperCamelCase__     ):



    def __init__(self   :   Optional[Any]       ,      __a   :   Union[str, Any]=ZeroShotClassificationArgumentHandler()       ,      *__a   :   Optional[int]       ,      **__a   :   List[str]			):
         UpperCAmelCase_	   =       args_parser
         super().__init__(*__a       ,      **__a			)
         if self.entailment_id == -1:
              logger.warning(
                  "Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to "
                  "-1. Define a descriptive label2id mapping in the model config to ensure correct outputs."			)



    @property
    def  _lowercase						(self   :   str			):
         for label, ind in self.model.config.labelaid.items():
              if label.lower().startswith("entail"			):
                   return ind
         return -1



    def  _lowercase						(self   :   Any       ,      __a   :   Any       ,      __a   :   int=True       ,      __a   :   Dict=True       ,      __a   :   Any=TruncationStrategy.ONLY_FIRST       ,      **__a   :   Tuple			):
         UpperCAmelCase_	   =       self.framework
         if self.tokenizer.pad_token is None:
              # Override for tokenizers not supporting padding
              logger.error(
                  "Tokenizer was not supporting padding necessary for zero-shot, attempting to use "
                  " `pad_token=eos_token`"			)
              UpperCAmelCase_	   =       self.tokenizer.eos_token
         try:
              UpperCAmelCase_	   =       self.tokenizer(
                  __a       ,      add_special_tokens=__a       ,      return_tensors=__a       ,      padding=__a       ,      truncation=__a       ,      )
         except Exception as e:
              if "too short" in str(__a			):
                   # tokenizers might yell that we want to truncate
                   # to a value that is not even reached by the input.
                   # In that case we don't want to truncate.
                   # It seems there's not a really better way to catch that
                   # exception.

                   UpperCAmelCase_	   =       self.tokenizer(
                       __a       ,      add_special_tokens=__a       ,      return_tensors=__a       ,      padding=__a       ,      truncation=TruncationStrategy.DO_NOT_TRUNCATE       ,      )
              else:
                   raise e

         return inputs



    def  _lowercase						(self   :   List[str]       ,      **__a   :   Tuple			):
         if kwargs.get("multi_class"       ,      __a			) is not None:
              UpperCAmelCase_	   =       kwargs["multi_class"]
              logger.warning(
                  "The `multi_class` argument has been deprecated and renamed to `multi_label`. "
                  "`multi_class` will be removed in a future version of Transformers."			)
         UpperCAmelCase_	   =       {}
         if "candidate_labels" in kwargs:
              UpperCAmelCase_	   =       self._args_parser._parse_labels(kwargs["candidate_labels"]			)
         if "hypothesis_template" in kwargs:
              UpperCAmelCase_	   =       kwargs["hypothesis_template"]

         UpperCAmelCase_	   =       {}
         if "multi_label" in kwargs:
              UpperCAmelCase_	   =       kwargs["multi_label"]
         return preprocess_params, {}, postprocess_params



    def __call__(self   :   Tuple       ,      __a   :   Union[str, List[str]]       ,      *__a   :   Optional[Any]       ,      **__a   :   Tuple       ,      ):
         if len(__a			) == 0:
              pass
         elif len(__a			) == 1 and "candidate_labels" not in kwargs:
              UpperCAmelCase_	   =       args[0]
         else:
              raise ValueError(f"""Unable to understand extra arguments {args}"""			)

         return super().__call__(__a       ,      **__a			)



    def  _lowercase						(self   :   Optional[int]       ,      __a   :   Optional[Any]       ,      __a   :   List[str]=None       ,      __a   :   Any="This example is {}."			):
         UpperCAmelCase_   ,			UpperCAmelCase_	   =       self._args_parser(__a       ,      __a       ,      __a			)

         for i, (candidate_label, sequence_pair) in enumerate(zip(__a       ,      __a			)			):
              UpperCAmelCase_	   =       self._parse_and_tokenize([sequence_pair]			)

              yield {
                  "candidate_label": candidate_label,
                  "sequence": sequences[0],
                  "is_last": i == len(__a			) - 1,
                  **model_input,
              }



    def  _lowercase						(self   :   List[str]       ,      __a   :   Any			):
         UpperCAmelCase_	   =       inputs["candidate_label"]
         UpperCAmelCase_	   =       inputs["sequence"]
         UpperCAmelCase_	   =       {k: inputs[k] for k in self.tokenizer.model_input_names}
         UpperCAmelCase_	   =       self.model(**__a			)

         UpperCAmelCase_	   =       {
             "candidate_label": candidate_label,
             "sequence": sequence,
             "is_last": inputs["is_last"],
             **outputs,
         }
         return model_outputs






    def  _lowercase						(self   :   Optional[Any]       ,      __a   :   List[str]       ,      __a   :   Tuple=False			):
         UpperCAmelCase_	   =       [outputs["candidate_label"] for outputs in model_outputs]
         UpperCAmelCase_	   =       [outputs["sequence"] for outputs in model_outputs]
         UpperCAmelCase_	   =       np.concatenate([output["logits"].numpy() for output in model_outputs]			)
         UpperCAmelCase_	   =       logits.shape[0]
         UpperCAmelCase_	   =       len(__a			)
         UpperCAmelCase_	   =       N // n
         UpperCAmelCase_	   =       logits.reshape((num_sequences, n, -1)			)

         if multi_label or len(__a			) == 1:
              # softmax over the entailment vs. contradiction dim for each label independently
              UpperCAmelCase_	   =       self.entailment_id
              UpperCAmelCase_	   =       -1 if entailment_id == 0 else 0
              UpperCAmelCase_	   =       reshaped_outputs[..., [contradiction_id, entailment_id]]
              UpperCAmelCase_	   =       np.exp(__a			) / np.exp(__a			).sum(-1       ,      keepdims=__a			)
              UpperCAmelCase_	   =       scores[..., 1]
         else:
              # softmax the "entailment" logits over all candidate labels
              UpperCAmelCase_	   =       reshaped_outputs[..., self.entailment_id]
              UpperCAmelCase_	   =       np.exp(__a			) / np.exp(__a			).sum(-1       ,      keepdims=__a			)

         UpperCAmelCase_	   =       list(reversed(scores[0].argsort()			)			)
         return {
             "sequence": sequences[0],
             "labels": [candidate_labels[i] for i in top_inds],
             "scores": scores[0, top_inds].tolist(),
         }




