






import os
import sys
import tempfile

import torch

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





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case=()       ,			__snake_case=None       ,			__snake_case="no"       ,			__snake_case="29500"							):
     __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"       ,			__snake_case							) 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(__snake_case       ,			distributed_type="TPU"							)
          print(F"""Launching a training on {num_processes} TPU cores."""							)
          xmp.spawn(__snake_case       ,			args=__snake_case       ,			nprocs=__snake_case       ,			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(*__snake_case							)
     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=__snake_case       ,			master_addr="127.0.01"       ,			master_port=__snake_case       ,			mixed_precision=__snake_case							):
                    __lowerCAmelCase             =       PrepareForLaunch(__snake_case       ,			distributed_type="MULTI_GPU"							)
                    print(F"""Launching training on {num_processes} GPUs."""							)
                    try:
                         start_processes(__snake_case       ,			args=__snake_case       ,			nprocs=__snake_case       ,			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(*__snake_case							)





def    __lowerCAmelCase   (    __snake_case       ,			__snake_case=()       ,			__snake_case=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=__snake_case       ,			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(__snake_case       ,			debug=__snake_case							)
               start_processes(__snake_case       ,			args=__snake_case       ,			nprocs=__snake_case       ,			start_method="fork"							)














import unittest

from transformers import is_torch_available
from transformers.testing_utils import require_torch


if is_torch_available():
 import torch

 from transformers.generation import DisjunctiveConstraint



@require_torch
class 				_UpperCamelCase      (unittest.TestCase      ):


      def 			__UpperCAmelCase		(						self						)->						List[Any]:
           # For consistency across different places the DisjunctiveConstraint is called,
           # dc.token_ids is a list of integers. It is also initialized only by integers.

           __lowerCAmelCase             =       [[1, 2, 4], [1, 2, 3, 4]]
           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)
           self.assertTrue(isinstance(dc.token_ids       ,    __UpperCamelCase						)						)

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint(torch.LongTensor([[1, 2, 4], [1, 2, 3]]						)						)

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint([torch.LongTensor([1, 2, 4]						), torch.LongTensor([1, 2, 3, 4, 5]						)]						)


      def 			__UpperCAmelCase		(						self						)->						Tuple:
           # We can't have constraints that are complete subsets of another. This leads to a preverse
           # interpretation of "constraint fulfillment": does generating [1,2,3] fulfill the constraint?
           # It would mean that it generated [1,2] which fulfills it, but it's in the middle of potentially
           # fulfilling [1,2,3,4]. If we believe that [1,2,3] does fulfill the constraint, then the algorithm
           # will necessarily never reach [1,2,3,4], giving users a false sense of control (better to just not allow it).
           __lowerCAmelCase             =       [[1, 2], [1, 2, 3, 4]]

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint(__UpperCamelCase						)  # fails here


      def 			__UpperCAmelCase		(						self						)->						List[Any]:
           __lowerCAmelCase             =       [[1, 2, 3], [1, 2, 4]]

           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           __lowerCAmelCase             =       stepped is True and completed is False and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           __lowerCAmelCase             =       stepped is True and completed is False and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(3						)
           __lowerCAmelCase             =       stepped is True and completed is True and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.current_seq == [1, 2, 3]						)


      def 			__UpperCAmelCase		(						self						)->						int:
           __lowerCAmelCase             =       [[1, 2, 3], [1, 2, 4, 5], [1, 2, 5]]

           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(4						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2, 4]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(5						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.current_seq == [1, 2, 4, 5]						)

           dc.reset()

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.remaining() == 3						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.remaining() == 2						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(5						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.remaining() == 0						)
           self.assertTrue(dc.current_seq == [1, 2, 5]						)






