

'''simple docstring'''




import inspect
import warnings

import torch

from .state import AcceleratorState, GradientState
from .utils import DistributedType, honor_type, is_tpu_available


if is_tpu_available(check_device=False):
  import torch_xla.core.xla_model as xm


def       lowerCamelCase__		(						SCREAMING_SNAKE_CASE      :   str       ,   SCREAMING_SNAKE_CASE      :   Dict						):
  if isinstance(SCREAMING_SNAKE_CASE       ,   (list, tuple)						):
    return honor_type(SCREAMING_SNAKE_CASE       ,   (move_to_device(SCREAMING_SNAKE_CASE       ,   SCREAMING_SNAKE_CASE						) for t in state)						)
  elif isinstance(SCREAMING_SNAKE_CASE       ,   SCREAMING_SNAKE_CASE						):
    return type(SCREAMING_SNAKE_CASE						)({k: move_to_device(SCREAMING_SNAKE_CASE       ,   SCREAMING_SNAKE_CASE						) for k, v in state.items()}						)
  elif isinstance(SCREAMING_SNAKE_CASE       ,   torch.Tensor						):
    return state.to(SCREAMING_SNAKE_CASE						)
  return state



class        lowercase_	(		torch.optim.Optimizer ):

  '''simple docstring'''





  def __init__(     self   , a_   , a_=True   , a_=None     )							->				List[str]:


    """simple docstring"""
    UpperCAmelCase													=	optimizer
    UpperCAmelCase													=	scaler
    UpperCAmelCase													=	AcceleratorState()
    UpperCAmelCase													=	GradientState()
    UpperCAmelCase													=	device_placement
    UpperCAmelCase													=	False
    UpperCAmelCase													=	None

    # Handle device placement
    if device_placement:
      UpperCAmelCase													=	self.optimizer.state_dict()
      if self.accelerator_state.distributed_type == DistributedType.TPU:
        xm.send_cpu_data_to_device(a_   , self.accelerator_state.device     )
      else:
        UpperCAmelCase													=	move_to_device(a_   , self.accelerator_state.device     )
      self.optimizer.load_state_dict(a_     )
  @property
  def 						snake_case_			(     self     )							->				int:


    """simple docstring"""
    return self.optimizer.state
  @state.setter
  def 						snake_case_			(     self   , a_     )							->				Union[str, Any]:


    """simple docstring"""
    UpperCAmelCase													=	state
  @property
  def 						snake_case_			(     self     )							->				List[str]:


    """simple docstring"""
    return self.optimizer.param_groups
  @param_groups.setter
  def 						snake_case_			(     self   , a_     )							->				List[str]:


    """simple docstring"""
    UpperCAmelCase													=	param_groups
  @property
  def 						snake_case_			(     self     )							->				Optional[Any]:


    """simple docstring"""
    return self.optimizer.defaults
  @defaults.setter
  def 						snake_case_			(     self   , a_     )							->				Optional[int]:


    """simple docstring"""
    UpperCAmelCase													=	defaults
  def 						snake_case_			(     self   , a_     )							->				Optional[Any]:


    """simple docstring"""
    self.optimizer.add_param_group(a_     )
  def 						snake_case_			(     self   , a_     )							->				int:


    """simple docstring"""
    if self.accelerator_state.distributed_type == DistributedType.TPU and self.device_placement:
      xm.send_cpu_data_to_device(a_   , self.accelerator_state.device     )
    self.optimizer.load_state_dict(a_     )
  def 						snake_case_			(     self     )							->				Optional[int]:


    """simple docstring"""
    return self.optimizer.state_dict()
  def 						snake_case_			(     self   , a_=None     )							->				Dict:


    """simple docstring"""
    if self.gradient_state.sync_gradients:
      UpperCAmelCase													=	'set_to_none' in inspect.signature(self.optimizer.zero_grad     ).parameters
      if accept_arg:
        if set_to_none is None:
          UpperCAmelCase													=	False
        self.optimizer.zero_grad(set_to_none=a_     )
      else:
        if set_to_none is not None:
          raise ValueError('`set_to_none` for Optimizer.zero_grad` is not supported by this optimizer.'     )
        self.optimizer.zero_grad()
  def 						snake_case_			(     self   , a_=None     )							->				Dict:


    """simple docstring"""
    if self.gradient_state.sync_gradients:
      if self.accelerator_state.distributed_type == DistributedType.TPU:
        UpperCAmelCase													=	{'closure': closure} if closure is not None else {}
        xm.optimizer_step(self.optimizer   , optimizer_args=a_     )
      elif self.scaler is not None:
        UpperCAmelCase													=	False
        if self._last_scale is None:
          # `get_scale` is an async operation requiring full synchronization
          # on CPU and GPUs before finishing. As a result, we store away
          # the prior one to reduce the call overhead
          UpperCAmelCase													=	self.scaler.get_scale()
          UpperCAmelCase													=	True
        self.scaler.step(self.optimizer   , a_     )
        self.scaler.update()
        UpperCAmelCase													=	self.scaler.get_scale()
        if not new_scale:
          # If we reduced the loss scale, it means the optimizer step was skipped because of gradient overflow.
          UpperCAmelCase													=	scale_after < self._last_scale
        UpperCAmelCase													=	scale_after

      else:
        self.optimizer.step(a_     )
  def 						snake_case_			(     self   , a_     )							->				Tuple:


    """simple docstring"""
    for param_group in self.optimizer.param_groups:
      UpperCAmelCase													=	[parameters_map.get(a_   , a_     ) for p in param_group['params']]
  @property
  def 						snake_case_			(     self     )							->				Optional[int]:


    """simple docstring"""
    warnings.warn(
        'The `is_overflow` property is deprecated and will be removed in version 1.0 of Accelerate use '
        '`optimizer.step_was_skipped` instead.'   , a_   , )
    return self._is_overflow
  @property
  def 						snake_case_			(     self     )							->				List[Any]:


    """simple docstring"""
    return self._is_overflow
  def __getstate__(     self     )							->				int:


    """simple docstring"""
    return self.__dict__.copy()





  def __setstate__(     self   , a_     )							->				List[Any]:


    """simple docstring"""
    self.__dict__.update(a_     )





'''simple docstring'''




from collections import OrderedDict
from dataclasses import fields
from typing import Any, Tuple

import numpy as np

from .import_utils import is_torch_available


def       lowerCamelCase__		(						SCREAMING_SNAKE_CASE      :   Optional[Any]						):
  if is_torch_available():
    import torch

    if isinstance(SCREAMING_SNAKE_CASE       ,   torch.Tensor						):
      return True

  return isinstance(SCREAMING_SNAKE_CASE       ,   np.ndarray						)



class        lowercase_	(		a ):

  '''simple docstring'''





  def 						snake_case_			(     self     )							->				List[str]:


    """simple docstring"""
    UpperCAmelCase													=	fields(self     )

    # Safety and consistency checks
    if not len(a_     ):
      raise ValueError(F'''{self.__class__.__name__} has no fields.'''     )

    UpperCAmelCase													=	getattr(self   , class_fields[0].name     )
    UpperCAmelCase													=	all(getattr(self   , field.name     ) is None for field in class_fields[1:]     )

    if other_fields_are_none and isinstance(a_   , a_     ):
      for key, value in first_field.items():
        UpperCAmelCase													=	value
    else:
      for field in class_fields:
        UpperCAmelCase													=	getattr(self   , field.name     )
        if v is not None:
          UpperCAmelCase													=	v
  def __delitem__(     self   , *a_   , **a_     )							->				int:


    """simple docstring"""
    raise Exception(F'''You cannot use ``__delitem__`` on a {self.__class__.__name__} instance.'''     )
  def 						snake_case_			(     self   , *a_   , **a_     )							->				Tuple:


    """simple docstring"""
    raise Exception(F'''You cannot use ``setdefault`` on a {self.__class__.__name__} instance.'''     )
  def 						snake_case_			(     self   , *a_   , **a_     )							->				int:


    """simple docstring"""
    raise Exception(F'''You cannot use ``pop`` on a {self.__class__.__name__} instance.'''     )
  def 						snake_case_			(     self   , *a_   , **a_     )							->				Dict:


    """simple docstring"""
    raise Exception(F'''You cannot use ``update`` on a {self.__class__.__name__} instance.'''     )
  def __getitem__(     self   , a_     )							->				Tuple:


    """simple docstring"""
    if isinstance(a_   , a_     ):
      UpperCAmelCase													=	dict(self.items()     )
      return inner_dict[k]
    else:
      return self.to_tuple()[k]
  def __setattr__(     self   , a_   , a_     )							->				Dict:


    """simple docstring"""
    if name in self.keys() and value is not None:
      # Don't call self.__setitem__ to avoid recursion errors
      super().__setitem__(a_   , a_     )
    super().__setattr__(a_   , a_     )
  def __setitem__(     self   , a_   , a_     )							->				str:


    """simple docstring"""
    # Will raise a KeyException if needed
    super().__setitem__(a_   , a_     )
    # Don't call self.__setattr__ to avoid recursion errors
    super().__setattr__(a_   , a_     )





  def 						snake_case_			(     self     )							->				Tuple[Any]:


    """simple docstring"""
    return tuple(self[k] for k in self.keys()     )


