from typing import List, Optional, TypeVar

from .arrow_dataset import Dataset, _concatenate_map_style_datasets, _interleave_map_style_datasets
from .dataset_dict import DatasetDict, IterableDatasetDict
from .info import DatasetInfo
from .iterable_dataset import IterableDataset, _concatenate_iterable_datasets, _interleave_iterable_datasets
from .splits import NamedSplit
from .utils import logging
from .utils.py_utils import Literal


SCREAMING_SNAKE_CASE__		:					Optional[Any]						=					logging.get_logger(__name__)


SCREAMING_SNAKE_CASE__		:					str						=					TypeVar("DatasetType", Dataset, IterableDataset)







def     _a				(      lowercase__  :			List[DatasetType]     ,  lowercase__  :			Optional[List[float]] = None     ,  lowercase__  :			Optional[int] = None     ,  lowercase__  :			Optional[DatasetInfo] = None     ,  lowercase__  :			Optional[NamedSplit] = None     ,  lowercase__  :			Literal["first_exhausted", "all_exhausted"] = "first_exhausted"     ,  ):







     '''simple docstring'''


     from .arrow_dataset import Dataset
     from .iterable_dataset import IterableDataset

     if not datasets:
          raise ValueError('Unable to interleave an empty list of datasets.' )
     for i, dataset in enumerate(snake_case__ ):
          if not isinstance(snake_case__     ,  (Dataset, IterableDataset) ):
               if isinstance(snake_case__     ,  (DatasetDict, IterableDatasetDict) ):
                    if not dataset:
                         raise ValueError(
                             f'''Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} '''
                             'is an empty dataset dictionary.' )
                    raise ValueError(
                        f'''Dataset at position {i} has at least one split: {list(snake_case__ )}\n'''
                        f'''Please pick one to interleave with the other datasets, for example: dataset[\'{next(iter(snake_case__ ) )}\']''' )
               raise ValueError(
                   f'''Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} is a {type(snake_case__ ).__name__}.''' )
          if i == 0:
               SCREAMING_SNAKE_CASE__			,							SCREAMING_SNAKE_CASE__				:				Tuple			=		(
                   (Dataset, IterableDataset) if isinstance(snake_case__     ,  snake_case__ ) else (IterableDataset, Dataset)
               )
          elif not isinstance(snake_case__     ,  snake_case__ ):
               raise ValueError(
                   f'''Unable to interleave a {dataset_type.__name__} (at position 0) with a {other_type.__name__} (at position {i}). Expected a list of Dataset objects or a list of IterableDataset objects.''' )
     if stopping_strategy not in ["first_exhausted", "all_exhausted"]:
          raise ValueError(f'''{stopping_strategy} is not supported. Please enter a valid stopping_strategy.''' )
     if dataset_type is Dataset:
          return _interleave_map_style_datasets(
              snake_case__     ,  snake_case__     ,  snake_case__     ,  info=snake_case__     ,  split=snake_case__     ,  stopping_strategy=snake_case__ )
     else:
          return _interleave_iterable_datasets(
              snake_case__     ,  snake_case__     ,  snake_case__     ,  info=snake_case__     ,  split=snake_case__     ,  stopping_strategy=snake_case__ )







def     _a				(      lowercase__  :			List[DatasetType]     ,  lowercase__  :			Optional[DatasetInfo] = None     ,  lowercase__  :			Optional[NamedSplit] = None     ,  lowercase__  :			int = 0     ,  ):







     '''simple docstring'''


     if not dsets:
          raise ValueError('Unable to concatenate an empty list of datasets.' )
     for i, dataset in enumerate(snake_case__ ):
          if not isinstance(snake_case__     ,  (Dataset, IterableDataset) ):
               if isinstance(snake_case__     ,  (DatasetDict, IterableDatasetDict) ):
                    if not dataset:
                         raise ValueError(
                             f'''Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} '''
                             'is an empty dataset dictionary.' )
                    raise ValueError(
                        f'''Dataset at position {i} has at least one split: {list(snake_case__ )}\n'''
                        f'''Please pick one to interleave with the other datasets, for example: dataset[\'{next(iter(snake_case__ ) )}\']''' )
               raise ValueError(
                   f'''Expected a list of Dataset objects or a list of IterableDataset objects, but element at position {i} is a {type(snake_case__ ).__name__}.''' )
          if i == 0:
               SCREAMING_SNAKE_CASE__			,							SCREAMING_SNAKE_CASE__				:				str			=		(
                   (Dataset, IterableDataset) if isinstance(snake_case__     ,  snake_case__ ) else (IterableDataset, Dataset)
               )
          elif not isinstance(snake_case__     ,  snake_case__ ):
               raise ValueError(
                   f'''Unable to interleave a {dataset_type.__name__} (at position 0) with a {other_type.__name__} (at position {i}). Expected a list of Dataset objects or a list of IterableDataset objects.''' )
     if dataset_type is Dataset:
          return _concatenate_map_style_datasets(snake_case__     ,  info=snake_case__     ,  split=snake_case__     ,  axis=snake_case__ )
     else:
          return _concatenate_iterable_datasets(snake_case__     ,  info=snake_case__     ,  split=snake_case__     ,  axis=snake_case__ )




# Copyright 2023 The HuggingFace Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import torch

from accelerate import PartialState
from accelerate.utils.operations import broadcast, gather, gather_object, pad_across_processes, reduce







def     _a				(      lowercase__  :			Any ):







     '''simple docstring'''


     return (torch.arange(state.num_processes ) + 1.0 + (state.num_processes * state.process_index)).to(state.device )







def     _a				(      lowercase__  :			Tuple ):







     '''simple docstring'''


     SCREAMING_SNAKE_CASE__				:				int			=		create_tensor(lowercase__ )
     SCREAMING_SNAKE_CASE__				:				Optional[Any]			=		gather(lowercase__ )
     assert gathered_tensor.tolist() == list(range(1     ,  state.num_processes**2 + 1 ) )







def     _a				(      lowercase__  :			List[Any] ):







     '''simple docstring'''


     SCREAMING_SNAKE_CASE__				:				str			=		[state.process_index]
     SCREAMING_SNAKE_CASE__				:				Any			=		gather_object(lowercase__ )
     assert len(lowercase__ ) == state.num_processes, f'''{gathered_obj}, {len(lowercase__ )} != {state.num_processes}'''
     assert gathered_obj == list(range(state.num_processes ) ), f'''{gathered_obj} != {list(range(state.num_processes ) )}'''







def     _a				(      lowercase__  :			str ):







     '''simple docstring'''


     SCREAMING_SNAKE_CASE__				:				Optional[Any]			=		create_tensor(lowercase__ )
     SCREAMING_SNAKE_CASE__				:				Optional[Any]			=		broadcast(lowercase__ )
     assert broadcasted_tensor.shape == torch.Size([state.num_processes] )
     assert broadcasted_tensor.tolist() == list(range(1     ,  state.num_processes + 1 ) )







def     _a				(      lowercase__  :			int ):







     '''simple docstring'''


     if state.is_main_process:
          SCREAMING_SNAKE_CASE__				:				Optional[int]			=		torch.arange(state.num_processes + 1 ).to(state.device )
     else:
          SCREAMING_SNAKE_CASE__				:				List[Any]			=		torch.arange(state.num_processes ).to(state.device )
     SCREAMING_SNAKE_CASE__				:				Any			=		pad_across_processes(lowercase__ )
     assert padded_tensor.shape == torch.Size([state.num_processes + 1] )
     if not state.is_main_process:
          assert padded_tensor.tolist() == list(range(0     ,  state.num_processes ) ) + [0]







def     _a				(      lowercase__  :			Optional[Any] ):







     '''simple docstring'''


     if state.num_processes != 2:
          return
     SCREAMING_SNAKE_CASE__				:				List[Any]			=		create_tensor(lowercase__ )
     SCREAMING_SNAKE_CASE__				:				str			=		reduce(lowercase__     ,  'sum' )
     SCREAMING_SNAKE_CASE__				:				Union[str, Any]			=		torch.tensor([4.0, 6] ).to(state.device )
     assert torch.allclose(lowercase__     ,  lowercase__ ), f'''{reduced_tensor} != {truth_tensor}'''







def     _a				(      lowercase__  :			int ):







     '''simple docstring'''


     if state.num_processes != 2:
          return
     SCREAMING_SNAKE_CASE__				:				Any			=		create_tensor(lowercase__ )
     SCREAMING_SNAKE_CASE__				:				List[Any]			=		reduce(lowercase__     ,  'mean' )
     SCREAMING_SNAKE_CASE__				:				Optional[Any]			=		torch.tensor([2.0, 3] ).to(state.device )
     assert torch.allclose(lowercase__     ,  lowercase__ ), f'''{reduced_tensor} != {truth_tensor}'''







def     _a				(      lowercase__  :			int ):







     '''simple docstring'''


     main()







def     _a				(      ):







     '''simple docstring'''


     SCREAMING_SNAKE_CASE__				:				int			=		PartialState()
     state.print(f'''State: {state}''' )
     state.print('testing gather' )
     test_gather(lowercase__ )
     state.print('testing gather_object' )
     test_gather_object(lowercase__ )
     state.print('testing broadcast' )
     test_broadcast(lowercase__ )
     state.print('testing pad_across_processes' )
     test_pad_across_processes(lowercase__ )
     state.print('testing reduce_sum' )
     test_reduce_sum(lowercase__ )
     state.print('testing reduce_mean' )
     test_reduce_mean(lowercase__ )


if __name__ == "__main__":
      main()



