



import os
import sys
import tempfile

import torch

from .state import AcceleratorState
from .utils import PrecisionType, PrepareForLaunch, is_mps_available, patch_environment






def 				SCREAMING_SNAKE_CASE__							(       UpperCamelCase__:							Optional[int]					,   UpperCamelCase__:							Tuple=()					,   UpperCamelCase__:							List[Any]=None					,   UpperCamelCase__:							Dict="no"					,   UpperCamelCase__:							Any="29500"    ):
		SCREAMING_SNAKE_CASE__			=      False
		SCREAMING_SNAKE_CASE__			=      False
		if any(key.startswith("""KAGGLE"""    ) for key in os.environ.keys()    ):
				SCREAMING_SNAKE_CASE__			=      True
		elif "IPython" in sys.modules:
				SCREAMING_SNAKE_CASE__			=      """google.colab""" in str(sys.modules["""IPython"""].get_ipython()    )

		try:
				SCREAMING_SNAKE_CASE__			=      PrecisionType(mixed_precision.lower()    )
		except ValueError:
				raise ValueError(
				    f'''Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}.'''    )

		if (in_colab or in_kaggle) and (os.environ.get("""TPU_NAME"""					,   lowercase__    ) is not None):
				# TPU launch
				import torch_xla.distributed.xla_multiprocessing as xmp

				if len(AcceleratorState._shared_state    ) > 0:
						raise ValueError(
						    """To train on TPU in Colab or Kaggle Kernel, the `Accelerator` should only be initialized inside """
						    """your training function. Restart your notebook and make sure no cells initializes an """
						    """`Accelerator`."""    )
				if num_processes is None:
						SCREAMING_SNAKE_CASE__			=      8

				SCREAMING_SNAKE_CASE__			=      PrepareForLaunch(lowercase__					,   distributed_type="""TPU"""    )
				print(f'''Launching a training on {num_processes} TPU cores.'''    )
				xmp.spawn(lowercase__					,   args=lowercase__					,   nprocs=lowercase__					,   start_method="""fork"""    )
		elif in_colab:
				# No need for a distributed launch otherwise as it's either CPU or one GPU.
				if torch.cuda.is_available():
						print("""Launching training on one GPU."""    )
				else:
						print("""Launching training on one CPU."""    )
				function(*lowercase__    )
		else:
				if num_processes is None:
						raise ValueError(
						    """You have to specify the number of GPUs you would like to use, add `num_processes=...` to your call."""    )

				if num_processes > 1:
						# Multi-GPU launch
						from torch.multiprocessing import start_processes
						from torch.multiprocessing.spawn import ProcessRaisedException

						if len(AcceleratorState._shared_state    ) > 0:
								raise ValueError(
								    """To launch a multi-GPU training from your notebook, the `Accelerator` should only be initialized """
								    """inside your training function. Restart your notebook and make sure no cells initializes an """
								    """`Accelerator`."""    )

						if torch.cuda.is_initialized():
								raise ValueError(
								    """To launch a multi-GPU training from your notebook, you need to avoid running any instruction """
								    """using `torch.cuda` in any cell. Restart your notebook and make sure no cells use any CUDA """
								    """function."""    )

						# torch.distributed will expect a few environment variable to be here. We set the ones common to each
						# process here (the other ones will be set be the launcher).
						with patch_environment(
						    world_size=lowercase__					,   master_addr="""127.0.01"""					,   master_port=lowercase__					,   mixed_precision=lowercase__    ):
								SCREAMING_SNAKE_CASE__			=      PrepareForLaunch(lowercase__					,   distributed_type="""MULTI_GPU"""    )
								print(f'''Launching training on {num_processes} GPUs.'''    )
								try:
										start_processes(lowercase__					,   args=lowercase__					,   nprocs=lowercase__					,   start_method="""fork"""    )
								except ProcessRaisedException as e:
										if "Cannot re-initialize CUDA in forked subprocess" in e.args[0]:
												raise RuntimeError(
												    """CUDA has been initialized before the `notebook_launcher` could create a forked subprocess. """
												    """This likely stems from an outside import causing issues once the `notebook_launcher()` is called. """
												    """Please review your imports and test them when running the `notebook_launcher()` to identify """
												    """which one is problematic."""    ) from e

				else:
						# No need for a distributed launch otherwise as it's either CPU, GPU or MPS.
						if is_mps_available():
								SCREAMING_SNAKE_CASE__			=      """1"""
								print("""Launching training on MPS."""    )
						elif torch.cuda.is_available():
								print("""Launching training on one GPU."""    )
						else:
								print("""Launching training on CPU."""    )
						function(*lowercase__    )






def 				SCREAMING_SNAKE_CASE__							(       UpperCamelCase__:							List[Any]					,   UpperCamelCase__:							Optional[int]=()					,   UpperCamelCase__:							List[Any]=2    ):
		from torch.multiprocessing import start_processes

		with tempfile.NamedTemporaryFile() as tmp_file:
				# torch.distributed will expect a few environment variable to be here. We set the ones common to each
				# process here (the other ones will be set be the launcher).
				with patch_environment(
				    world_size=lowercase__					,   master_addr="""127.0.01"""					,   master_port="""29500"""					,   accelerate_mixed_precision="""no"""					,   accelerate_debug_rdv_file=tmp_file.name					,   accelerate_use_cpu="""yes"""					,   ):
						SCREAMING_SNAKE_CASE__			=      PrepareForLaunch(lowercase__					,   debug=lowercase__    )
						start_processes(lowercase__					,   args=lowercase__					,   nprocs=lowercase__					,   start_method="""fork"""    )






from argparse import ArgumentParser

from datasets.commands.convert import ConvertCommand
from datasets.commands.dummy_data import DummyDataCommand
from datasets.commands.env import EnvironmentCommand
from datasets.commands.run_beam import RunBeamCommand
from datasets.commands.test import TestCommand
from datasets.utils.logging import set_verbosity_info






def 				SCREAMING_SNAKE_CASE__							(       UpperCamelCase__:							Any    ):
		return {key.lstrip("""-"""    ): value for key, value in zip(unknown_args[::2]					,   unknown_args[1::2]    )}






def 				SCREAMING_SNAKE_CASE__							(       ):
		SCREAMING_SNAKE_CASE__			=      ArgumentParser(
		    """HuggingFace Datasets CLI tool"""					,   usage="""datasets-cli <command> [<args>]"""					,   allow_abbrev=UpperCamelCase__    )
		SCREAMING_SNAKE_CASE__			=      parser.add_subparsers(help="""datasets-cli command helpers"""    )
		set_verbosity_info()

		# Register commands
		ConvertCommand.register_subcommand(UpperCamelCase__    )
		EnvironmentCommand.register_subcommand(UpperCamelCase__    )
		TestCommand.register_subcommand(UpperCamelCase__    )
		RunBeamCommand.register_subcommand(UpperCamelCase__    )
		DummyDataCommand.register_subcommand(UpperCamelCase__    )

		# Parse args
		SCREAMING_SNAKE_CASE__	,						SCREAMING_SNAKE_CASE__			=      parser.parse_known_args()
		if not hasattr(UpperCamelCase__					,   """func"""    ):
				parser.print_help()
				exit(1    )
		SCREAMING_SNAKE_CASE__			=      parse_unknown_args(UpperCamelCase__    )

		# Run
		SCREAMING_SNAKE_CASE__			=      args.func(UpperCamelCase__					,   **UpperCamelCase__    )
		service.run()


if __name__ == "__main__":
	main()