

'''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

lowercase__         =      logging.get_logger(__name__)




def 				UpperCamelCase(					UpperCAmelCase_  ,	UpperCAmelCase_  ,	UpperCAmelCase_  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=None     ):
 # Recurse if needed
 if "." in tensor_name:
  UpperCAmelCase	:     Any						 =			tensor_name.split('.'     )
  for split in splits[:-1]:
   UpperCAmelCase	:     Optional[Any]						 =			getattr(UpperCAmelCase_  ,	UpperCAmelCase_     )
   if new_module is None:
    raise ValueError(F"""{module} has no attribute {split}."""     )
   UpperCAmelCase	:     Tuple						 =			new_module
  UpperCAmelCase	:     Optional[int]						 =			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}."""     )
 UpperCAmelCase	:     Optional[Any]						 =			tensor_name in module._buffers
 UpperCAmelCase	:     Optional[Any]						 =			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}."""     )

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

 if is_abit or is_abit:
  UpperCAmelCase	:     Union[str, Any]						 =			module._parameters[tensor_name]
  if param.device.type != "cuda":
   if value is None:
    UpperCAmelCase	:     Tuple						 =			old_value.to(UpperCAmelCase_     )
   elif isinstance(UpperCAmelCase_  ,	torch.Tensor     ):
    UpperCAmelCase	:     str						 =			value.to('cpu'     )
    if value.dtype == torch.inta:
     UpperCAmelCase	:     str						 =			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:
    UpperCAmelCase	:     Tuple						 =			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:
    UpperCAmelCase	:     Optional[Any]						 =			new_value.T

   UpperCAmelCase	:     List[str]						 =			old_value.__dict__
   if is_abit:
    UpperCAmelCase	:     Union[str, Any]						 =			bnb.nn.IntaParams(UpperCAmelCase_  ,	requires_grad=UpperCAmelCase_  ,	**UpperCAmelCase_     ).to(UpperCAmelCase_     )
   elif is_abit:
    UpperCAmelCase	:     Union[str, Any]						 =			bnb.nn.Paramsabit(UpperCAmelCase_  ,	requires_grad=UpperCAmelCase_  ,	**UpperCAmelCase_     ).to(UpperCAmelCase_     )

   UpperCAmelCase	:     Tuple						 =			new_value
   if fpaa_statistics is not None:
    setattr(module.weight  ,	'SCB'  ,	fpaa_statistics.to(UpperCAmelCase_     )     )

 else:
  if value is None:
   UpperCAmelCase	:     int						 =			old_value.to(UpperCAmelCase_     )
  elif isinstance(UpperCAmelCase_  ,	torch.Tensor     ):
   UpperCAmelCase	:     int						 =			value.to(UpperCAmelCase_     )
  else:
   UpperCAmelCase	:     int						 =			torch.tensor(UpperCAmelCase_  ,	device=UpperCAmelCase_     )

  if is_buffer:
   UpperCAmelCase	:     List[Any]						 =			new_value
  else:
   UpperCAmelCase	:     Optional[Any]						 =			nn.Parameter(UpperCAmelCase_  ,	requires_grad=old_value.requires_grad     )
   UpperCAmelCase	:     Any						 =			new_value




def 				UpperCamelCase(					UpperCAmelCase_  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=False     ):
 for name, module in model.named_children():
  if current_key_name is None:
   UpperCAmelCase	:     str						 =			[]
  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_     ):
      UpperCAmelCase ,			UpperCAmelCase	:     int						 =			module.weight.shape
     else:
      UpperCAmelCase	:     str						 =			module.in_features
      UpperCAmelCase	:     List[Any]						 =			module.out_features

     if quantization_config.quantization_method() == "llm_int8":
      UpperCAmelCase	:     Optional[int]						 =			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  ,	)
      UpperCAmelCase	:     str						 =			True
     else:
      if (
          quantization_config.llm_inta_skip_modules is not None
          and name in quantization_config.llm_inta_skip_modules
      ):
       pass
      else:
       UpperCAmelCase	:     List[Any]						 =			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  ,	)
       UpperCAmelCase	:     Any						 =			True
                    # Store the module class in case we need to transpose the weight later
     UpperCAmelCase	:     List[str]						 =			type(UpperCAmelCase_     )
     # Force requires grad to False to avoid unexpected errors
     model._modules[name].requires_grad_(UpperCAmelCase_     )
  if len(list(module.children()     )     ) > 0:
   UpperCAmelCase ,			UpperCAmelCase	:     List[Any]						 =			_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 				UpperCamelCase(					UpperCAmelCase_  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=None  ,	UpperCAmelCase_=None     ):
 UpperCAmelCase	:     Dict						 =			['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
 UpperCAmelCase ,			UpperCAmelCase	:     Dict						 =			_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 				UpperCamelCase(					*UpperCAmelCase_  ,	**UpperCAmelCase_     ):
 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 				UpperCamelCase(					*UpperCAmelCase_  ,	**UpperCAmelCase_     ):
 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 				UpperCamelCase(					UpperCAmelCase_     ):
 UpperCAmelCase	:     str						 =			deepcopy(UpperCAmelCase_     )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
 tied_model.tie_weights()

 UpperCAmelCase	:     Optional[int]						 =			find_tied_parameters(UpperCAmelCase_     )
 # For compatibility with Accelerate < 0.18
 if isinstance(UpperCAmelCase_  ,	UpperCAmelCase_     ):
  UpperCAmelCase	:     Tuple						 =			sum(list(tied_params.values()     )  ,	[]     ) + list(tied_params.keys()     )
 else:
  UpperCAmelCase	:     List[str]						 =			sum(UpperCAmelCase_  ,	[]     )
 UpperCAmelCase	:     Optional[int]						 =			len(UpperCAmelCase_     ) > 0

 # Check if it is a base model
 UpperCAmelCase	:     int						 =			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
 UpperCAmelCase	:     List[Any]						 =			list(model.named_children()     )
 UpperCAmelCase	:     Tuple						 =			[list_modules[-1][0]]

 # add last module together with tied weights
 UpperCAmelCase	:     Optional[Any]						 =			set(UpperCAmelCase_     ) - set(UpperCAmelCase_     )
 UpperCAmelCase	:     Optional[Any]						 =			list(set(UpperCAmelCase_     )     ) + list(UpperCAmelCase_     )

 # remove ".weight" from the keys
 UpperCAmelCase	:     int						 =			['.weight', '.bias']
 UpperCAmelCase	:     Dict						 =			[]
 for name in list_untouched:
  for name_to_remove in names_to_remove:
   if name_to_remove in name:
    UpperCAmelCase	:     Any						 =			name.replace(UpperCAmelCase_  ,	''     )
  filtered_module_names.append(UpperCAmelCase_     )

 return filtered_module_names







'''simple docstring'''

from collections.abc import Iterator, MutableMapping
from dataclasses import dataclass
from typing import Generic, TypeVar

lowercase__         =      TypeVar("KEY")
lowercase__         =      TypeVar("VAL")




@dataclass(frozen=_snake_case	,       slots=_snake_case							)
class 	A_			(    Generic[KEY, VAL]							):






     '''simple docstring'''



     UpperCAmelCase_						:     KEY
     UpperCAmelCase_						:     VAL




class 	A_			(    _Item							):






     '''simple docstring'''



     def __init__(		self			:					Any	)						->     None:
      super().__init__(lowercase_					,      lowercase_	)




     def __bool__(		self			:					List[str]	)						->     bool:
      return False



lowercase__         =      _DeletedItem()




class 	A_			(    MutableMapping[KEY, VAL]							):






     '''simple docstring'''



     def __init__(		self			:					Optional[int]					,      lowercase_			:					int = 8					,      lowercase_			:					float = 0.75	)						->     None:
      UpperCAmelCase	:     Dict						 =			initial_block_size
      UpperCAmelCase	:     list[_Item | None]						 =			[None] * initial_block_size
      assert 0.0 < capacity_factor < 1.0
      UpperCAmelCase	:     Any						 =			capacity_factor
      UpperCAmelCase	:     Union[str, Any]						 =			0


     def        UpperCAmelCase_	(		self			:					str					,      lowercase_			:					KEY	)						->     int:
      return hash(lowercase_	) % len(self._buckets	)


     def        UpperCAmelCase_	(		self			:					Any					,      lowercase_			:					int	)						->     int:
      return (ind + 1) % len(self._buckets	)


     def        UpperCAmelCase_	(		self			:					Dict					,      lowercase_			:					int					,      lowercase_			:					KEY					,      lowercase_			:					VAL	)						->     bool:
      UpperCAmelCase	:     List[Any]						 =			self._buckets[ind]
      if not stored:
       UpperCAmelCase	:     Dict						 =			_Item(lowercase_					,      lowercase_	)
       self._len += 1
       return True
      elif stored.key == key:
       UpperCAmelCase	:     Dict						 =			_Item(lowercase_					,      lowercase_	)
       return True
      else:
       return False


     def        UpperCAmelCase_	(		self			:					Any	)						->     bool:
      UpperCAmelCase	:     List[str]						 =			len(self._buckets	) * self._capacity_factor
      return len(self	) >= int(lowercase_	)


     def        UpperCAmelCase_	(		self			:					Optional[int]	)						->     bool:
      if len(self._buckets	) <= self._initial_block_size:
       return False
      UpperCAmelCase	:     Optional[int]						 =			len(self._buckets	) * self._capacity_factor / 2
      return len(self	) < limit


     def        UpperCAmelCase_	(		self			:					Dict					,      lowercase_			:					int	)						->     None:
      UpperCAmelCase	:     int						 =			self._buckets
      UpperCAmelCase	:     List[str]						 =			[None] * new_size
      UpperCAmelCase	:     Dict						 =			0
      for item in old_buckets:
       if item:
        self._add_item(item.key					,      item.val	)


     def        UpperCAmelCase_	(		self			:					Dict	)						->     None:
      self._resize(len(self._buckets	) * 2	)


     def        UpperCAmelCase_	(		self			:					Union[str, Any]	)						->     None:
      self._resize(len(self._buckets	) // 2	)


     def        UpperCAmelCase_	(		self			:					Union[str, Any]					,      lowercase_			:					KEY	)						->     Iterator[int]:
      UpperCAmelCase	:     Dict						 =			self._get_bucket_index(lowercase_	)
      for _ in range(len(self._buckets	)	):
       yield ind
       UpperCAmelCase	:     Union[str, Any]						 =			self._get_next_ind(lowercase_	)


     def        UpperCAmelCase_	(		self			:					Dict					,      lowercase_			:					KEY					,      lowercase_			:					VAL	)						->     None:
      for ind in self._iterate_buckets(lowercase_	):
       if self._try_set(lowercase_					,      lowercase_					,      lowercase_	):
        break


     def __setitem__(		self			:					Union[str, Any]					,      lowercase_			:					KEY					,      lowercase_			:					VAL	)						->     None:
      if self._is_full():
       self._size_up()

      self._add_item(lowercase_					,      lowercase_	)


     def __delitem__(		self			:					Tuple					,      lowercase_			:					KEY	)						->     None:
      for ind in self._iterate_buckets(lowercase_	):
       UpperCAmelCase	:     int						 =			self._buckets[ind]
       if item is None:
        raise KeyError(lowercase_	)
       if item is _deleted:
        continue
       if item.key == key:
        UpperCAmelCase	:     Union[str, Any]						 =			_deleted
        self._len -= 1
        break
      if self._is_sparse():
       self._size_down()


     def __getitem__(		self			:					Dict					,      lowercase_			:					KEY	)						->     VAL:
      for ind in self._iterate_buckets(lowercase_	):
       UpperCAmelCase	:     List[str]						 =			self._buckets[ind]
       if item is None:
        break
       if item is _deleted:
        continue
       if item.key == key:
        return item.val
      raise KeyError(lowercase_	)


     def __len__(		self			:					Optional[Any]	)						->     int:
      return self._len


     def __iter__(		self			:					int	)						->     Iterator[KEY]:
      yield from (item.key for item in self._buckets if item)




     def __repr__(		self			:					Optional[Any]	)						->     str:
      UpperCAmelCase	:     int						 =			' ,'.join(
          f"""{item.key}: {item.val}""" for item in self._buckets if item	)
      return f"""HashMap({val_string})"""




