






'''simple docstring'''



import baseaa
import io
import json
import os
from copy import deepcopy

from ..optimizer import AcceleratedOptimizer
from ..scheduler import AcceleratedScheduler
class 				__SCREAMING_SNAKE_CASE							:




      def __init__(	self			, lowerCamelCase   )				->Tuple:



         '''simple docstring'''
         if isinstance(lowerCamelCase			, lowerCamelCase   ):
            # Don't modify user's data should they want to reuse it (e.g. in tests), because once we
            # modified it, it will not be accepted here again, since `auto` values would have been overridden
            __a					  =     deepcopy(lowerCamelCase   )
         elif os.path.exists(lowerCamelCase   ):
            with io.open(lowerCamelCase			, 'r'			, encoding='utf-8'   ) as f:
               __a					  =     json.load(lowerCamelCase   )
         else:
            try:
               __a					  =     baseaa.urlsafe_baadecode(lowerCamelCase   ).decode('utf-8'   )
               __a					  =     json.loads(lowerCamelCase   )
            except (UnicodeDecodeError, AttributeError, ValueError):
               raise ValueError(
                   F"""Expected a string path to an existing deepspeed config, or a dictionary, or a base64 encoded string. Received: {config_file_or_dict}"""   )

         __a					  =     config

         self.set_stage_and_offload()




      def 			__UpperCamelCase				(	self   )				->str:



         '''simple docstring'''
         # zero stage - this is done as early as possible, before model is created, to allow
         # ``is_deepspeed_zero3_enabled`` query and getting to the early deepspeed config object
         # during ``zero.Init()`` which needs to know the dtype, and some other hparams.
         __a					  =     self.get_value('zero_optimization.stage'			, -1   )

         # offload
         __a					  =     False
         if self.is_zeroa() or self.is_zeroa():
            __a					  =     set(['cpu', 'nvme']   )
            __a					  =     set(
                [
                    self.get_value('zero_optimization.offload_optimizer.device'   ),
                    self.get_value('zero_optimization.offload_param.device'   ),
                ]   )
            if len(offload_devices & offload_devices_valid   ) > 0:
               __a					  =     True




      def 			__UpperCamelCase				(	self			, lowerCamelCase   )				->int:



         '''simple docstring'''
         __a					  =     self.config

         # find the config node of interest if it exists
         __a					  =     ds_key_long.split('.'   )
         __a					  =     nodes.pop()
         for node in nodes:
            __a					  =     config.get(lowerCamelCase   )
            if config is None:
               return None, ds_key

         return config, ds_key




      def 			__UpperCamelCase				(	self			, lowerCamelCase			, lowerCamelCase=None   )				->Any:



         '''simple docstring'''
         __a  ,      __a					  =     self.find_config_node(lowerCamelCase   )
         if config is None:
            return default
         return config.get(lowerCamelCase			, lowerCamelCase   )




      def 			__UpperCamelCase				(	self			, lowerCamelCase			, lowerCamelCase=False   )				->Optional[Any]:



         '''simple docstring'''
         __a					  =     self.config

         # find the config node of interest if it exists
         __a					  =     ds_key_long.split('.'   )
         for node in nodes:
            __a					  =     config
            __a					  =     config.get(lowerCamelCase   )
            if config is None:
               if must_exist:
                  raise ValueError(F"""Can't find {ds_key_long} entry in the config: {self.config}"""   )
               else:
                  return

        # if found remove it
         if parent_config is not None:
            parent_config.pop(lowerCamelCase   )




      def 			__UpperCamelCase				(	self			, lowerCamelCase   )				->List[Any]:



         '''simple docstring'''
         __a					  =     self.get_value(lowerCamelCase   )
         return False if value is None else bool(lowerCamelCase   )




      def 			__UpperCamelCase				(	self			, lowerCamelCase   )				->Dict:



         '''simple docstring'''
         __a					  =     self.get_value(lowerCamelCase   )
         return False if value is None else not bool(lowerCamelCase   )




      def 			__UpperCamelCase				(	self   )				->Optional[Any]:



         '''simple docstring'''
         return self._stage == 2




      def 			__UpperCamelCase				(	self   )				->Dict:



         '''simple docstring'''
         return self._stage == 3






      def 			__UpperCamelCase				(	self   )				->Union[str, Any]:



         '''simple docstring'''
         return self._offload







class 				__SCREAMING_SNAKE_CASE							:




      def __init__(	self			, lowerCamelCase   )				->Tuple:



         '''simple docstring'''
         __a					  =     engine






      def 			__UpperCamelCase				(	self			, lowerCamelCase			, **lowerCamelCase   )				->int:



         '''simple docstring'''
         # runs backpropagation and handles mixed precision
         self.engine.backward(lowerCamelCase			, **lowerCamelCase   )

         # Deepspeed's `engine.step` performs the following operations:
         # - gradient accumulation check
         # - gradient clipping
         # - optimizer step
         # - zero grad
         # - checking overflow
         # - lr_scheduler step (only if engine.lr_scheduler is not None)
         self.engine.step()
         # and this plugin overrides the above calls with no-ops when Accelerate runs under
         # Deepspeed, but allows normal functionality for non-Deepspeed cases thus enabling a simple
         # training loop that works transparently under many training regimes.







class 				__SCREAMING_SNAKE_CASE							(				_lowerCAmelCase  ):




      def __init__(	self			, lowerCamelCase   )				->Dict:



         '''simple docstring'''
         super().__init__(lowerCamelCase			, device_placement=lowerCamelCase			, scaler=lowerCamelCase   )
         __a					  =     hasattr(self.optimizer			, 'overflow'   )




      def 			__UpperCamelCase				(	self			, lowerCamelCase=None   )				->Union[str, Any]:



         '''simple docstring'''
         pass  # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed




      def 			__UpperCamelCase				(	self   )				->Tuple:



         '''simple docstring'''
         pass  # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed






      @property
      def 			__UpperCamelCase				(	self   )				->Tuple:



         '''simple docstring'''
         if self.__has_overflow__:
            return self.optimizer.overflow
         return False







class 				__SCREAMING_SNAKE_CASE							(				_lowerCAmelCase  ):




      def __init__(	self			, lowerCamelCase			, lowerCamelCase   )				->str:



         '''simple docstring'''
         super().__init__(lowerCamelCase			, lowerCamelCase   )






      def 			__UpperCamelCase				(	self   )				->Union[str, Any]:



         '''simple docstring'''
         pass  # `accelerator.backward(loss)` is doing that automatically. Therefore, its implementation is not needed







class 				__SCREAMING_SNAKE_CASE							:




      def __init__(	self			, lowerCamelCase			, lowerCamelCase=0.001			, lowerCamelCase=0			, **lowerCamelCase   )				->List[Any]:



         '''simple docstring'''
         __a					  =     params
         __a					  =     lr
         __a					  =     weight_decay
         __a					  =     kwargs







class 				__SCREAMING_SNAKE_CASE							:




      def __init__(	self			, lowerCamelCase			, lowerCamelCase=None			, lowerCamelCase=0			, **lowerCamelCase   )				->List[str]:



         '''simple docstring'''
         __a					  =     optimizer
         __a					  =     total_num_steps
         __a					  =     warmup_num_steps
         __a					  =     kwargs







'''simple docstring'''



from timeit import timeit

__UpperCamelCase   :							int         =   {
    """MALAYALAM""": True,
    """String""": False,
    """rotor""": True,
    """level""": True,
    """A""": True,
    """BB""": True,
    """ABC""": False,
    """amanaplanacanalpanama""": True,  # "a man a plan a canal panama"
}
# Ensure our test data is valid
assert all((key == key[::-1]) is value for key, value in test_data.items())



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						str     )	->      bool:

   """simple docstring"""
   __a					  =     0
   __a					  =     len(SCREAMING_SNAKE_CASE__     ) - 1
   while start_i < end_i:
      if s[start_i] == s[end_i]:
         start_i += 1
         end_i -= 1
      else:
         return False
   return True



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						str     )	->      bool:

   """simple docstring"""
   __a					  =     len(SCREAMING_SNAKE_CASE__     ) // 2
   __a					  =     len(SCREAMING_SNAKE_CASE__     )

   # We need to traverse till half of the length of string
   # as we can get access of the i'th last element from
   # i'th index.
   # eg: [0,1,2,3,4,5] => 4th index can be accessed
   # with the help of 1st index (i==n-i-1)
   # where n is length of string
   return all(s[i] == s[n - i - 1] for i in range(SCREAMING_SNAKE_CASE__     )     )



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						str     )	->      bool:

   """simple docstring"""
   if len(SCREAMING_SNAKE_CASE__     ) <= 2:
      return True
   if s[0] == s[len(SCREAMING_SNAKE_CASE__     ) - 1]:
      return is_palindrome_recursive(s[1:-1]     )
   else:
      return False



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						str     )	->      bool:

   """simple docstring"""
   return s == s[::-1]



def  __UpperCAmelCase						(					SCREAMING_SNAKE_CASE__:						str     )	->      None:

   """simple docstring"""
   __a					  =     f"""all({name}(key) is value for key, value in test_data.items())"""
   __a					  =     f"""from __main__ import test_data, {name}"""
   __a					  =     500000
   __a					  =     timeit(stmt=SCREAMING_SNAKE_CASE__,       setup=SCREAMING_SNAKE_CASE__,       number=SCREAMING_SNAKE_CASE__     )
   print(f"""{name:<35} finished {number:,} runs in {result:.5f} seconds"""     )


if __name__ == "__main__":
 for key, value in test_data.items():
  assert is_palindrome(key) is is_palindrome_recursive(key)
  assert is_palindrome(key) is is_palindrome_slice(key)
  print(f"""{key:21} {value}""")
 print("""a man a plan a canal panama""")

 # finished 500,000 runs in 0.46793 seconds
 benchmark_function("""is_palindrome_slice""")
 # finished 500,000 runs in 0.85234 seconds
 benchmark_function("""is_palindrome""")
 # finished 500,000 runs in 1.32028 seconds
 benchmark_function("""is_palindrome_recursive""")
 # finished 500,000 runs in 2.08679 seconds
 benchmark_function("""is_palindrome_traversal""")