

"""simple docstring"""




import os
import sys
import tempfile

import torch

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



def 	UpperCAmelCase__   (				A__	,    A__=()	,    A__=None	,    A__="no"	,    A__="29500"   )      ->      Union[str, Any]:




   """simple docstring"""
   lowerCamelCase__						=			False
   lowerCamelCase__						=			False
   if any(key.startswith("KAGGLE"   ) for key in os.environ.keys()   ):
      lowerCamelCase__						=			True
   elif "IPython" in sys.modules:
      lowerCamelCase__						=			"google.colab" in str(sys.modules["IPython"].get_ipython()   )

   try:
      lowerCamelCase__						=			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"	,    A__   ) 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:
         lowerCamelCase__						=			8

      lowerCamelCase__						=			PrepareForLaunch(A__	,    distributed_type="TPU"   )
      print(f'Launching a training on {num_processes} TPU cores.'   )
      xmp.spawn(A__	,    args=A__	,    nprocs=A__	,    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(*A__   )
   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=A__	,    master_addr="127.0.01"	,    master_port=A__	,    mixed_precision=A__   ):
            lowerCamelCase__						=			PrepareForLaunch(A__	,    distributed_type="MULTI_GPU"   )
            print(f'Launching training on {num_processes} GPUs.'   )
            try:
               start_processes(A__	,    args=A__	,    nprocs=A__	,    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():
            lowerCamelCase__						=			"1"
            print("Launching training on MPS."   )
         elif torch.cuda.is_available():
            print("Launching training on one GPU."   )
         else:
            print("Launching training on CPU."   )
         function(*A__   )



def 	UpperCAmelCase__   (				A__	,    A__=()	,    A__=2   )      ->      Any:




   """simple docstring"""
   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=A__	,    master_addr="127.0.01"	,    master_port="29500"	,    accelerate_mixed_precision="no"	,    accelerate_debug_rdv_file=tmp_file.name	,    accelerate_use_cpu="yes"	,    ):
         lowerCamelCase__						=			PrepareForLaunch(A__	,    debug=A__   )
         start_processes(A__	,    args=A__	,    nprocs=A__	,    start_method="fork"   )







"""simple docstring"""




from __future__ import annotations

from typing import Any



def 	UpperCAmelCase__   (				A__   )      ->      None:




   """simple docstring"""
   create_state_space_tree(A__	,    []	,    0   )



def 	UpperCAmelCase__   (				A__	,    A__	,    A__   )      ->      None:




   """simple docstring"""

   if index == len(A__   ):
      print(A__   )
      return

   create_state_space_tree(A__	,    A__	,    index + 1   )
   current_subsequence.append(sequence[index]   )
   create_state_space_tree(A__	,    A__	,    index + 1   )
   current_subsequence.pop()


if __name__ == "__main__":
     SCREAMING_SNAKE_CASE_     :			list[Any]	  =			[3, 1, 2, 4]
     generate_all_subsequences(seq)

     seq.clear()
     seq.extend(['''A''', '''B''', '''C'''])
     generate_all_subsequences(seq)




