"""simple docstring"""
import importlib.metadata
import warnings
from copy import deepcopy

from packaging import version

from ..utils import logging
from .import_utils import is_accelerate_available, is_bitsandbytes_available


if is_bitsandbytes_available():
     import bitsandbytes as bnb
     import torch
     import torch.nn as nn

     from ..pytorch_utils import ConvaD

if is_accelerate_available():
     from accelerate import init_empty_weights
     from accelerate.utils import find_tied_parameters

SCREAMING_SNAKE_CASE__   =					logging.get_logger(__name__)





def 				lowerCAmelCase__      (     _UpperCamelCase    :			List[str]	,     _UpperCamelCase    :			Union[str, Any]	,     _UpperCamelCase    :			List[Any]	,     _UpperCamelCase    :			Optional[Any]=None	,     _UpperCamelCase    :			Dict=None   )   ->			Union[str, Any]:





      """simple docstring"""






      if "." in tensor_name:
            snake_case        =     tensor_name.split('.'   )
            for split in splits[:-1]:
                  snake_case        =     getattr(_UpperCamelCase	,     _UpperCamelCase   )
                  if new_module is None:
                        raise ValueError(f"""{module} has no attribute {split}."""   )
                  snake_case        =     new_module
            snake_case        =     splits[-1]

      if tensor_name not in module._parameters and tensor_name not in module._buffers:
            raise ValueError(f"""{module} does not have a parameter or a buffer named {tensor_name}."""   )
      snake_case        =     tensor_name in module._buffers
      snake_case        =     getattr(_UpperCamelCase	,     _UpperCamelCase   )

      if old_value.device == torch.device('meta'   ) and device not in ["meta", torch.device('meta'   )] and value is None:
            raise ValueError(f"""{tensor_name} is on the meta device, we need a `value` to put in on {device}."""   )

      snake_case        =     False
      snake_case        =     False
      if is_buffer or not is_bitsandbytes_available():
            snake_case        =     False
            snake_case        =     False
      else:
            snake_case        =     hasattr(bnb.nn	,     'Params4bit'   ) and isinstance(module._parameters[tensor_name]	,     bnb.nn.Paramsabit   )
            snake_case        =     isinstance(module._parameters[tensor_name]	,     bnb.nn.IntaParams   )

      if is_abit or is_abit:
            snake_case        =     module._parameters[tensor_name]
            if param.device.type != "cuda":
                  if value is None:
                        snake_case        =     old_value.to(_UpperCamelCase   )
                  elif isinstance(_UpperCamelCase	,     torch.Tensor   ):
                        snake_case        =     value.to('cpu'   )
                        if value.dtype == torch.inta:
                              snake_case        =     version.parse(importlib.metadata.version('bitsandbytes'   )   ) > version.parse(
                                  '0.37.2'   )
                              if not is_abit_serializable:
                                    raise ValueError(
                                        'Detected int8 weights but the version of bitsandbytes is not compatible with int8 serialization. '
                                        'Make sure to download the latest `bitsandbytes` version. `pip install --upgrade bitsandbytes`.'   )
                  else:
                        snake_case        =     torch.tensor(_UpperCamelCase	,     device='cpu'   )

                  # Support models using `Conv1D` in place of `nn.Linear` (e.g. gpt2) by transposing the weight matrix prior to quantization.
                  # Since weights are saved in the correct "orientation", we skip transposing when loading.
                  if issubclass(module.source_cls	,     _UpperCamelCase   ) and fpaa_statistics is None:
                        snake_case        =     new_value.T

                  snake_case        =     old_value.__dict__
                  if is_abit:
                        snake_case        =     bnb.nn.IntaParams(_UpperCamelCase	,     requires_grad=_UpperCamelCase	,     **_UpperCamelCase   ).to(_UpperCamelCase   )
                  elif is_abit:
                        snake_case        =     bnb.nn.Paramsabit(_UpperCamelCase	,     requires_grad=_UpperCamelCase	,     **_UpperCamelCase   ).to(_UpperCamelCase   )

                  snake_case        =     new_value
                  if fpaa_statistics is not None:
                        setattr(module.weight	,     'SCB'	,     fpaa_statistics.to(_UpperCamelCase   )   )

      else:
            if value is None:
                  snake_case        =     old_value.to(_UpperCamelCase   )
            elif isinstance(_UpperCamelCase	,     torch.Tensor   ):
                  snake_case        =     value.to(_UpperCamelCase   )
            else:
                  snake_case        =     torch.tensor(_UpperCamelCase	,     device=_UpperCamelCase   )

            if is_buffer:
                  snake_case        =     new_value
            else:
                  snake_case        =     nn.Parameter(_UpperCamelCase	,     requires_grad=old_value.requires_grad   )
                  snake_case        =     new_value





def 				lowerCAmelCase__      (     _UpperCamelCase    :			List[str]	,     _UpperCamelCase    :			Tuple=None	,     _UpperCamelCase    :			Tuple=None	,     _UpperCamelCase    :			Optional[Any]=None	,     _UpperCamelCase    :			Optional[int]=False   )   ->			Optional[int]:





      """simple docstring"""






      for name, module in model.named_children():
            if current_key_name is None:
                  snake_case        =     []
            current_key_name.append(_UpperCamelCase   )

            if (isinstance(_UpperCamelCase	,     nn.Linear   ) or isinstance(_UpperCamelCase	,     _UpperCamelCase   )) and name not in modules_to_not_convert:
                  # Check if the current key is not in the `modules_to_not_convert`
                  if not any(key in '.'.join(_UpperCamelCase   ) for key in modules_to_not_convert   ):
                        with init_empty_weights():
                              if isinstance(_UpperCamelCase	,     _UpperCamelCase   ):
                                    snake_case   ,snake_case        =     module.weight.shape
                              else:
                                    snake_case        =     module.in_features
                                    snake_case        =     module.out_features

                              if quantization_config.quantization_method() == "llm_int8":
                                    snake_case        =     bnb.nn.LinearabitLt(
                                        _UpperCamelCase	,     _UpperCamelCase	,     module.bias is not None	,     has_fpaa_weights=quantization_config.llm_inta_has_fpaa_weight	,     threshold=quantization_config.llm_inta_threshold	,     )
                                    snake_case        =     True
                              else:
                                    if (
                                        quantization_config.llm_inta_skip_modules is not None
                                        and name in quantization_config.llm_inta_skip_modules
                                    ):
                                          pass
                                    else:
                                          snake_case        =     bnb.nn.Linearabit(
                                              _UpperCamelCase	,     _UpperCamelCase	,     module.bias is not None	,     quantization_config.bnb_abit_compute_dtype	,     compress_statistics=quantization_config.bnb_abit_use_double_quant	,     quant_type=quantization_config.bnb_abit_quant_type	,     )
                                          snake_case        =     True
                    # Store the module class in case we need to transpose the weight later
                              snake_case        =     type(_UpperCamelCase   )
                              # Force requires grad to False to avoid unexpected errors
                              model._modules[name].requires_grad_(_UpperCamelCase   )
            if len(list(module.children()   )   ) > 0:
                  snake_case   ,snake_case        =     _replace_with_bnb_linear(
                      _UpperCamelCase	,     _UpperCamelCase	,     _UpperCamelCase	,     _UpperCamelCase	,     has_been_replaced=_UpperCamelCase	,     )
            # Remove the last key for recursion
            current_key_name.pop(-1   )
      return model, has_been_replaced





def 				lowerCAmelCase__      (     _UpperCamelCase    :			List[str]	,     _UpperCamelCase    :			str=None	,     _UpperCamelCase    :			List[Any]=None	,     _UpperCamelCase    :			Union[str, Any]=None   )   ->			Union[str, Any]:





      """simple docstring"""






      snake_case        =     ['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
      snake_case   ,snake_case        =     _replace_with_bnb_linear(
          _UpperCamelCase	,     _UpperCamelCase	,     _UpperCamelCase	,     _UpperCamelCase   )

      if not has_been_replaced:
            logger.warning(
                'You are loading your model in 8bit or 4bit but no linear modules were found in your model.'
                ' Please double check your model architecture, or submit an issue on github if you think this is'
                ' a bug.'   )

      return model





def 				lowerCAmelCase__      (     *_UpperCamelCase    :			Any	,     **_UpperCamelCase    :			int   )   ->			str:





      """simple docstring"""






      warnings.warn(
          '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'	,     _UpperCamelCase	,     )
      return replace_with_bnb_linear(*_UpperCamelCase	,     **_UpperCamelCase   )





def 				lowerCAmelCase__      (     *_UpperCamelCase    :			Optional[int]	,     **_UpperCamelCase    :			Dict   )   ->			Tuple:





      """simple docstring"""






      warnings.warn(
          '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'	,     _UpperCamelCase	,     )
      return set_module_quantized_tensor_to_device(*_UpperCamelCase	,     **_UpperCamelCase   )





def 				lowerCAmelCase__      (     _UpperCamelCase    :			List[Any]   )   ->			Dict:





      """simple docstring"""






      snake_case        =     deepcopy(_UpperCamelCase   )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
      tied_model.tie_weights()

      snake_case        =     find_tied_parameters(_UpperCamelCase   )
      # For compatibility with Accelerate < 0.18
      if isinstance(_UpperCamelCase	,     _UpperCamelCase   ):
            snake_case        =     sum(list(tied_params.values()   )	,     []   ) + list(tied_params.keys()   )
      else:
            snake_case        =     sum(_UpperCamelCase	,     []   )
      snake_case        =     len(_UpperCamelCase   ) > 0

      # Check if it is a base model
      snake_case        =     not hasattr(_UpperCamelCase	,     model.base_model_prefix   )

      # Ignore this for base models (BertModel, GPT2Model, etc.)
      if (not has_tied_params) and is_base_model:
            return []

      # otherwise they have an attached head
      snake_case        =     list(model.named_children()   )
      snake_case        =     [list_modules[-1][0]]

      # add last module together with tied weights
      snake_case        =     set(_UpperCamelCase   ) - set(_UpperCamelCase   )
      snake_case        =     list(set(_UpperCamelCase   )   ) + list(_UpperCamelCase   )

      # remove ".weight" from the keys
      snake_case        =     ['.weight', '.bias']
      snake_case        =     []
      for name in list_untouched:
            for name_to_remove in names_to_remove:
                  if name_to_remove in name:
                        snake_case        =     name.replace(_UpperCamelCase	,     ''   )
            filtered_module_names.append(_UpperCamelCase   )

      return filtered_module_names



"""simple docstring"""
def 				lowerCAmelCase__      (     _UpperCamelCase    :			str   )   ->			bool:





						"""simple docstring"""






						if not all(x.isalpha() for x in string   ):
												raise ValueError('String must only contain alphabetic characters.'   )

						snake_case        =     sorted(string.lower()   )
						return len(_UpperCamelCase   ) == len(set(_UpperCamelCase   )   )


if __name__ == "__main__":
					SCREAMING_SNAKE_CASE__   =					input("Enter a string ").strip()

					SCREAMING_SNAKE_CASE__   =					is_isogram(input_str)
					print(f"""{input_str} is {'an' if isogram else 'not an'} isogram.""")


