






from abc import ABC, abstractmethod
from typing import Optional, Union

from .. import Dataset, DatasetDict, Features, IterableDataset, IterableDatasetDict, NamedSplit
from ..utils.typing import NestedDataStructureLike, PathLike




class       snake_case__ (				lowercase_):

       '''simple docstring'''



       def __init__(				self      ,    a__ = None      ,    a__ = None      ,    a__ = None      ,    a__ = None      ,    a__ = False      ,    a__ = False      ,    a__ = None      ,    **a__      ,    )			->   List[Any]:






            '''simple docstring'''





            __snake_case      :str 							=    path_or_paths
            __snake_case      :Any 							=    split if split or isinstance(a__      ,    a__     ) else """train"""
            __snake_case      :Any 							=    features
            __snake_case      :List[str] 							=    cache_dir
            __snake_case      :str 							=    keep_in_memory
            __snake_case      :Union[str, Any] 							=    streaming
            __snake_case      :List[str] 							=    num_proc
            __snake_case      :Any 							=    kwargs



       @abstractmethod
       def        __lowercase    (				self     )			->   Union[Dataset, DatasetDict, IterableDataset, IterableDatasetDict]:






            '''simple docstring'''





            pass




class       snake_case__ (				lowercase_):

       '''simple docstring'''



       def __init__(				self      ,    a__ = None      ,    a__ = None      ,    a__ = False      ,    a__ = False      ,    a__ = None      ,    **a__      ,    )			->   Optional[Any]:






            '''simple docstring'''





            __snake_case      :List[Any] 							=    features
            __snake_case      :Optional[int] 							=    cache_dir
            __snake_case      :Any 							=    keep_in_memory
            __snake_case      :Tuple 							=    streaming
            __snake_case      :Optional[Any] 							=    num_proc
            __snake_case      :Dict 							=    kwargs



       @abstractmethod
       def        __lowercase    (				self     )			->   Union[Dataset, IterableDataset]:






            '''simple docstring'''





            pass










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       snake_case__ (				lowercase_):

       '''simple docstring'''



       def __init__(				self      ,    a__=0.01      ,    a__=10_00     )			->   List[Any]:






            '''simple docstring'''





            __snake_case      :int 							=    p_stop
            __snake_case      :List[Any] 							=    max_length



       def __iter__(				self     )			->   Optional[int]:






            '''simple docstring'''





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




class       snake_case__ (				unittest.TestCase):

       '''simple docstring'''



       def        __lowercase    (				self      ,    a__      ,    a__      ,    a__=False      ,    a__=True     )			->   List[Any]:






            '''simple docstring'''





            __snake_case      :Optional[Any] 							=    [
                BatchSamplerShard(a__      ,    2      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )
                for i in range(2     )
            ]
            __snake_case      :Union[str, Any] 							=    [list(a__     ) for batch_sampler_shard in batch_sampler_shards]
            if not split_batches:
                 self.assertListEqual([len(a__     ) for shard in batch_sampler_shards]      ,    [len(a__     ) for e in expected]     )
            self.assertListEqual(a__      ,    a__     )



       def        __lowercase    (				self     )			->   Any:






            '''simple docstring'''





            __snake_case      :Optional[Any] 							=    BatchSampler(range(24     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :Dict 							=    [
                [[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(a__      ,    a__     )

            __snake_case      :Optional[Any] 							=    BatchSampler(range(24     )      ,    batch_size=3      ,    drop_last=a__     )
            # Expected shouldn't change
            self.check_batch_sampler_shards(a__      ,    a__     )

            # Check the shards when the dataset is a round multiple of batch size but not total batch size.
            __snake_case      :List[str] 							=    BatchSampler(range(21     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :Optional[Any] 							=    [
                [[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(a__      ,    a__     )

            __snake_case      :List[Any] 							=    BatchSampler(range(21     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :Optional[int] 							=    [
                [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
                [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
            ]
            self.check_batch_sampler_shards(a__      ,    a__     )

            # Check the shards when the dataset is not a round multiple of batch size but has a multiple of
            # num_processes batch.
            __snake_case      :Optional[Any] 							=    BatchSampler(range(22     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :List[str] 							=    [
                [[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(a__      ,    a__     )

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

            # Check the shards when the dataset is not a round multiple of batch size but and has not a multiple of
            # num_processes batch.
            __snake_case      :List[str] 							=    BatchSampler(range(20     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :int 							=    [
                [[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(a__      ,    a__     )

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

            # Check the shards when the dataset is very small.
            __snake_case      :Dict 							=    BatchSampler(range(2     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :Optional[Any] 							=    [[[0, 1, 0]], [[1, 0, 1]]]
            self.check_batch_sampler_shards(a__      ,    a__     )

            __snake_case      :Union[str, Any] 							=    BatchSampler(range(2     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :List[str] 							=    [[], []]
            self.check_batch_sampler_shards(a__      ,    a__     )



       def        __lowercase    (				self     )			->   Dict:






            '''simple docstring'''





            __snake_case      :Optional[int] 							=    BatchSampler(range(24     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Any 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__     )

            __snake_case      :List[Any] 							=    BatchSampler(range(24     )      ,    batch_size=4      ,    drop_last=a__     )
            # Expected shouldn't change
            self.check_batch_sampler_shards(a__      ,    a__      ,    split_batches=a__     )

            # Check the shards when the dataset is not a round multiple of batch size.
            __snake_case      :List[Any] 							=    BatchSampler(range(22     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Optional[int] 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__     )

            __snake_case      :List[Any] 							=    BatchSampler(range(22     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Union[str, Any] 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__     )

            # Check the shards when the dataset is not a round multiple of batch size or num_processes.
            __snake_case      :Union[str, Any] 							=    BatchSampler(range(21     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Union[str, Any] 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__     )

            __snake_case      :Any 							=    BatchSampler(range(21     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Tuple 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__     )

            # Check the shards when the dataset is very small.
            __snake_case      :str 							=    BatchSampler(range(2     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Dict 							=    [[[0, 1]], [[0, 1]]]
            self.check_batch_sampler_shards(a__      ,    a__      ,    split_batches=a__     )

            __snake_case      :Optional[Any] 							=    BatchSampler(range(2     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :List[Any] 							=    [[], []]
            self.check_batch_sampler_shards(a__      ,    a__      ,    split_batches=a__     )



       def        __lowercase    (				self     )			->   List[Any]:






            '''simple docstring'''





            __snake_case      :Tuple 							=    BatchSampler(range(24     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :int 							=    [
                [[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(a__      ,    a__      ,    even_batches=a__     )

            __snake_case      :List[Any] 							=    BatchSampler(range(24     )      ,    batch_size=3      ,    drop_last=a__     )
            # Expected shouldn't change
            self.check_batch_sampler_shards(a__      ,    a__      ,    even_batches=a__     )

            # Check the shards when the dataset is a round multiple of batch size but not total batch size.
            __snake_case      :Any 							=    BatchSampler(range(21     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :List[str] 							=    [
                [[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(a__      ,    a__      ,    even_batches=a__     )

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

            # Check the shards when the dataset is not a round multiple of batch size but has a multiple of
            # num_processes batch.
            __snake_case      :int 							=    BatchSampler(range(22     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :Optional[Any] 							=    [
                [[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(a__      ,    a__      ,    even_batches=a__     )

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

            # Check the shards when the dataset is not a round multiple of batch size but and has not a multiple of
            # num_processes batch.
            __snake_case      :Dict 							=    BatchSampler(range(20     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :int 							=    [
                [[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(a__      ,    a__      ,    even_batches=a__     )

            __snake_case      :Optional[int] 							=    BatchSampler(range(20     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :List[Any] 							=    [
                [[0, 1, 2], [6, 7, 8], [12, 13, 14]],
                [[3, 4, 5], [9, 10, 11], [15, 16, 17]],
            ]
            self.check_batch_sampler_shards(a__      ,    a__      ,    even_batches=a__     )

            # Check the shards when the dataset is very small.
            __snake_case      :Union[str, Any] 							=    BatchSampler(range(2     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :List[Any] 							=    [[[0, 1]], []]
            self.check_batch_sampler_shards(a__      ,    a__      ,    even_batches=a__     )

            __snake_case      :List[str] 							=    BatchSampler(range(2     )      ,    batch_size=3      ,    drop_last=a__     )
            __snake_case      :int 							=    [[], []]
            self.check_batch_sampler_shards(a__      ,    a__      ,    even_batches=a__     )



       def        __lowercase    (				self     )			->   Dict:






            '''simple docstring'''





            __snake_case      :int 							=    BatchSampler(range(24     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Optional[int] 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

            __snake_case      :Dict 							=    BatchSampler(range(24     )      ,    batch_size=4      ,    drop_last=a__     )
            # Expected shouldn't change
            self.check_batch_sampler_shards(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

            # Check the shards when the dataset is not a round multiple of batch size.
            __snake_case      :List[Any] 							=    BatchSampler(range(22     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Dict 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

            __snake_case      :Dict 							=    BatchSampler(range(22     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Dict 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

            # Check the shards when the dataset is not a round multiple of batch size or num_processes.
            __snake_case      :Dict 							=    BatchSampler(range(21     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :List[Any] 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

            __snake_case      :int 							=    BatchSampler(range(21     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Tuple 							=    [
                [[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(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )

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

            __snake_case      :Any 							=    BatchSampler(range(2     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :List[str] 							=    [[], []]
            self.check_batch_sampler_shards(a__      ,    a__      ,    split_batches=a__      ,    even_batches=a__     )



       def        __lowercase    (				self     )			->   Optional[Any]:






            '''simple docstring'''





            __snake_case      :str 							=    [[0, 1, 2], [3, 4], [5, 6, 7, 8], [9, 10, 11], [12, 13]]
            __snake_case      :List[str] 							=    [BatchSamplerShard(a__      ,    2      ,    a__      ,    even_batches=a__     ) 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      ,    a__      ,    a__      ,    a__      ,    a__=False      ,    a__=2      ,    a__=False     )			->   List[str]:






            '''simple docstring'''





            random.seed(a__     )
            __snake_case      :Optional[int] 							=    list(a__     )

            __snake_case      :Union[str, Any] 							=    [
                IterableDatasetShard(
                    a__      ,    batch_size=a__      ,    drop_last=a__      ,    num_processes=a__      ,    process_index=a__      ,    split_batches=a__      ,    )
                for i in range(a__     )
            ]
            __snake_case      :Any 							=    []
            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(a__     )
                 iterable_dataset_lists.append(list(a__     )     )

            __snake_case      :Union[str, Any] 							=    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
            __snake_case      :str 							=    iterable_dataset_lists[0]
            for l in iterable_dataset_lists[1:]:
                 self.assertEqual(len(a__     )      ,    len(a__     )     )
                 self.assertTrue(len(a__     ) % shard_batch_size == 0     )

            __snake_case      :int 							=    []
            for idx in range(0      ,    len(a__     )      ,    a__     ):
                 for l in iterable_dataset_lists:
                      observed += l[idx : idx + shard_batch_size]

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



       def        __lowercase    (				self     )			->   Any:






            '''simple docstring'''





            __snake_case      :int 							=    42
            __snake_case      :Tuple 							=    RandomIterableDataset()

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

            # Edge case with a very small dataset
            __snake_case      :Optional[int] 							=    RandomIterableDataset(max_length=2     )

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



       def        __lowercase    (				self     )			->   Dict:






            '''simple docstring'''





            __snake_case      :str 							=    BatchSampler(range(16     )      ,    batch_size=4      ,    drop_last=a__     )
            __snake_case      :Optional[int] 							=    SkipBatchSampler(a__      ,    2     )
            self.assertListEqual(list(a__     )      ,    [[8, 9, 10, 11], [12, 13, 14, 15]]     )



       def        __lowercase    (				self     )			->   str:






            '''simple docstring'''





            __snake_case      :str 							=    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     )			->   Dict:






            '''simple docstring'''





            __snake_case      :Union[str, Any] 							=    DataLoader(list(range(16     )     )      ,    batch_size=4     )
            __snake_case      :Dict 							=    skip_first_batches(a__      ,    num_batches=2     )
            self.assertListEqual([t.tolist() for t in new_dataloader]      ,    [[8, 9, 10, 11], [12, 13, 14, 15]]     )



       def        __lowercase    (				self     )			->   Optional[Any]:






            '''simple docstring'''





            __snake_case      :Any 							=    DataLoaderShard(list(range(16     )     )      ,    batch_size=4     )
            for idx, _ in enumerate(a__     ):
                 self.assertEqual(dataloader.end_of_dataloader      ,    idx == 3     )

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



       def        __lowercase    (				self     )			->   Any:






            '''simple docstring'''





            Accelerator()
            __snake_case      :Union[str, Any] 							=    DataLoaderDispatcher(range(16     )      ,    batch_size=4     )
            for idx, _ in enumerate(a__     ):
                 self.assertEqual(dataloader.end_of_dataloader      ,    idx == 3     )

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


