'''simple docstring'''

def __UpperCamelCase( _A       :					int	,      _A       :					bool = False     ):
   '''simple docstring'''
   if n == 2:
      return True
   if not n % 2 or n < 2:
      return False
   if n > 5 and n % 10 not in (1, 3, 7, 9):  # can quickly check last digit
      return False
   if n > 3_31_70_44_06_46_79_88_73_85_96_19_81 and not allow_probable:
      raise ValueError(
          '''Warning: upper bound of deterministic test is exceeded. '''
          '''Pass allow_probable=True to allow probabilistic test. '''
          '''A return value of True indicates a probable prime.'''     )
   # array bounds provided by analysis
   UpperCAmelCase__				:					Any 					=	[
       20_47,
       1_37_36_53,
       25_32_60_01,
       32_15_03_17_51,
       2_15_23_02_89_87_47,
       3_47_47_49_66_03_83,
       3_41_55_00_71_72_83_21,
       1,
       3_82_51_23_05_65_46_41_30_51,
       1,
       1,
       31_86_65_85_78_34_03_11_51_16_74_61,
       3_31_70_44_06_46_79_88_73_85_96_19_81,
   ]

   UpperCAmelCase__				:					Union[str, Any] 					=	[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
   for idx, _p in enumerate(_A	,      1     ):
      if n < _p:
         # then we have our last prime to check
         UpperCAmelCase__				:					Dict 					=	primes[:idx]
         break
   UpperCAmelCase__					,   UpperCAmelCase__				:					List[str] 					=	n - 1, 0
   # break up n -1 into a power of 2 (s) and
   # remaining odd component
   # essentially, solve for d * 2 ** s == n - 1
   while d % 2 == 0:
      d //= 2
      s += 1
   for prime in plist:
      UpperCAmelCase__				:					Dict 					=	False
      for r in range(_A     ):
         UpperCAmelCase__				:					Tuple 					=	pow(_A	,      d * 2**r	,      _A     )
         # see article for analysis explanation for m
         if (r == 0 and m == 1) or ((m + 1) % n == 0):
            UpperCAmelCase__				:					Union[str, Any] 					=	True
            # this loop will not determine compositeness
            break
      if pr:
         continue
      # if pr is False, then the above loop never evaluated to true,
      # and the n MUST be composite
      return False
   return True







def __UpperCamelCase( ):
   '''simple docstring'''
   assert not miller_rabin(5_61     )
   assert miller_rabin(5_63     )
   # 2047

   assert not miller_rabin(83_82_01     )
   assert miller_rabin(83_82_07     )
   # 1_373_653

   assert not miller_rabin(17_31_60_01     )
   assert miller_rabin(17_31_60_17     )
   # 25_326_001

   assert not miller_rabin(30_78_38_66_41     )
   assert miller_rabin(30_78_38_66_53     )
   # 3_215_031_751

   assert not miller_rabin(1_71_30_45_57_48_01     )
   assert miller_rabin(1_71_30_45_57_48_19     )
   # 2_152_302_898_747

   assert not miller_rabin(2_77_97_99_72_83_07     )
   assert miller_rabin(2_77_97_99_72_83_27     )
   # 3_474_749_660_383

   assert not miller_rabin(1_13_85_00_23_90_94_41     )
   assert miller_rabin(1_13_85_00_23_90_95_27     )
   # 341_550_071_728_321

   assert not miller_rabin(1_27_50_41_01_88_48_80_43_51     )
   assert miller_rabin(1_27_50_41_01_88_48_80_43_91     )
   # 3_825_123_056_546_413_051

   assert not miller_rabin(7_96_66_46_44_58_50_77_87_79_18_67     )
   assert miller_rabin(7_96_66_46_44_58_50_77_87_79_19_51     )
   # 318_665_857_834_031_151_167_461

   assert not miller_rabin(55_28_40_67_74_46_64_78_97_66_03_33     )
   assert miller_rabin(55_28_40_67_74_46_64_78_97_66_03_59     )
   # 3_317_044_064_679_887_385_961_981
   # upper limit for probabilistic test


if __name__ == "__main__":
  test_miller_rabin()





'''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       :					Any	,      _A       :					List[str]=()	,      _A       :					List[str]=None	,      _A       :					Dict="no"	,      _A       :					List[str]="29500"     ):
   '''simple docstring'''
   UpperCAmelCase__				:					int 					=	False
   UpperCAmelCase__				:					List[str] 					=	False
   if any(key.startswith('''KAGGLE'''     ) for key in os.environ.keys()     ):
      UpperCAmelCase__				:					List[str] 					=	True
   elif "IPython" in sys.modules:
      UpperCAmelCase__				:					List[Any] 					=	'''google.colab''' in str(sys.modules['''IPython'''].get_ipython()     )

   try:
      UpperCAmelCase__				:					Tuple 					=	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:
         UpperCAmelCase__				:					Tuple 					=	8

      UpperCAmelCase__				:					Optional[Any] 					=	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     ):
            UpperCAmelCase__				:					str 					=	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():
            UpperCAmelCase__				:					Union[str, Any] 					=	'''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       :					List[str]	,      _A       :					Optional[Any]=()	,      _A       :					str=2     ):
   '''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'''	,      ):
         UpperCAmelCase__				:					Optional[int] 					=	PrepareForLaunch(_A	,      debug=_A     )
         start_processes(_A	,      args=_A	,      nprocs=_A	,      start_method='''fork'''     )




