




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

UpperCamelCase__ :   List[Any]						=							logging.get_logger(__name__)





def        __UpperCAmelCase						(							lowerCamelCase_ :     List[Any]  ,							lowerCamelCase_ :     Optional[Any]  ,							lowerCamelCase_ :     Any  ,							lowerCamelCase_ :     Optional[Any]=None  ,							lowerCamelCase_ :     Optional[int]=None  )       ->  int:







			"""simple docstring"""





			if "." in tensor_name:
						SCREAMING_SNAKE_CASE_   : List[str]					  =      tensor_name.split('.'  )
						for split in splits[:-1]:
									SCREAMING_SNAKE_CASE_   : Optional[Any]					  =      getattr(lowerCamelCase_  ,							lowerCamelCase_  )
									if new_module is None:
												raise ValueError(F'{module} has no attribute {split}.'  )
									SCREAMING_SNAKE_CASE_   : List[Any]					  =      new_module
						SCREAMING_SNAKE_CASE_   : List[str]					  =      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}.'  )
			SCREAMING_SNAKE_CASE_   : List[str]					  =      tensor_name in module._buffers
			SCREAMING_SNAKE_CASE_   : Tuple					  =      getattr(lowerCamelCase_  ,							lowerCamelCase_  )

			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}.'  )

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

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

									SCREAMING_SNAKE_CASE_   : Any					  =      old_value.__dict__
									if is_abit:
												SCREAMING_SNAKE_CASE_   : Optional[int]					  =      bnb.nn.IntaParams(lowerCamelCase_  ,							requires_grad=lowerCamelCase_  ,							**lowerCamelCase_  ).to(lowerCamelCase_  )
									elif is_abit:
												SCREAMING_SNAKE_CASE_   : str					  =      bnb.nn.Paramsabit(lowerCamelCase_  ,							requires_grad=lowerCamelCase_  ,							**lowerCamelCase_  ).to(lowerCamelCase_  )

									SCREAMING_SNAKE_CASE_   : Optional[int]					  =      new_value
									if fpaa_statistics is not None:
												setattr(module.weight  ,							'SCB'  ,							fpaa_statistics.to(lowerCamelCase_  )  )

			else:
						if value is None:
									SCREAMING_SNAKE_CASE_   : Union[str, Any]					  =      old_value.to(lowerCamelCase_  )
						elif isinstance(lowerCamelCase_  ,							torch.Tensor  ):
									SCREAMING_SNAKE_CASE_   : Any					  =      value.to(lowerCamelCase_  )
						else:
									SCREAMING_SNAKE_CASE_   : List[str]					  =      torch.tensor(lowerCamelCase_  ,							device=lowerCamelCase_  )

						if is_buffer:
									SCREAMING_SNAKE_CASE_   : Dict					  =      new_value
						else:
									SCREAMING_SNAKE_CASE_   : str					  =      nn.Parameter(lowerCamelCase_  ,							requires_grad=old_value.requires_grad  )
									SCREAMING_SNAKE_CASE_   : int					  =      new_value





def        __UpperCAmelCase						(							lowerCamelCase_ :     Tuple  ,							lowerCamelCase_ :     Optional[Any]=None  ,							lowerCamelCase_ :     str=None  ,							lowerCamelCase_ :     Optional[Any]=None  ,							lowerCamelCase_ :     Union[str, Any]=False  )       ->  Dict:







			"""simple docstring"""





			for name, module in model.named_children():
						if current_key_name is None:
									SCREAMING_SNAKE_CASE_   : str					  =      []
						current_key_name.append(lowerCamelCase_  )

						if (isinstance(lowerCamelCase_  ,							nn.Linear  ) or isinstance(lowerCamelCase_  ,							lowerCamelCase_  )) 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(lowerCamelCase_  ) for key in modules_to_not_convert  ):
												with init_empty_weights():
															if isinstance(lowerCamelCase_  ,							lowerCamelCase_  ):
																		SCREAMING_SNAKE_CASE_  ,    SCREAMING_SNAKE_CASE_   : List[Any]					  =      module.weight.shape
															else:
																		SCREAMING_SNAKE_CASE_   : str					  =      module.in_features
																		SCREAMING_SNAKE_CASE_   : List[Any]					  =      module.out_features

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





def        __UpperCAmelCase						(							lowerCamelCase_ :     Dict  ,							lowerCamelCase_ :     List[Any]=None  ,							lowerCamelCase_ :     Optional[int]=None  ,							lowerCamelCase_ :     str=None  )       ->  Tuple:







			"""simple docstring"""





			SCREAMING_SNAKE_CASE_   : int					  =      ['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
			SCREAMING_SNAKE_CASE_  ,    SCREAMING_SNAKE_CASE_   : str					  =      _replace_with_bnb_linear(
			    lowerCamelCase_  ,							lowerCamelCase_  ,							lowerCamelCase_  ,							lowerCamelCase_  )

			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						(							*lowerCamelCase_ :     int  ,							**lowerCamelCase_ :     Optional[Any]  )       ->  str:







			"""simple docstring"""





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





def        __UpperCAmelCase						(							*lowerCamelCase_ :     Tuple  ,							**lowerCamelCase_ :     Optional[Any]  )       ->  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'  ,							lowerCamelCase_  ,							)
			return set_module_quantized_tensor_to_device(*lowerCamelCase_  ,							**lowerCamelCase_  )





def        __UpperCAmelCase						(							lowerCamelCase_ :     str  )       ->  str:







			"""simple docstring"""





			SCREAMING_SNAKE_CASE_   : Any					  =      deepcopy(lowerCamelCase_  )  # this has 0 cost since it is done inside `init_empty_weights` context manager`
			tied_model.tie_weights()

			SCREAMING_SNAKE_CASE_   : str					  =      find_tied_parameters(lowerCamelCase_  )
			# For compatibility with Accelerate < 0.18
			if isinstance(lowerCamelCase_  ,							lowerCamelCase_  ):
						SCREAMING_SNAKE_CASE_   : Dict					  =      sum(list(tied_params.values()  )  ,							[]  ) + list(tied_params.keys()  )
			else:
						SCREAMING_SNAKE_CASE_   : List[Any]					  =      sum(lowerCamelCase_  ,							[]  )
			SCREAMING_SNAKE_CASE_   : Optional[Any]					  =      len(lowerCamelCase_  ) > 0

			# Check if it is a base model
			SCREAMING_SNAKE_CASE_   : Dict					  =      not hasattr(lowerCamelCase_  ,							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
			SCREAMING_SNAKE_CASE_   : List[str]					  =      list(model.named_children()  )
			SCREAMING_SNAKE_CASE_   : Dict					  =      [list_modules[-1][0]]

			# add last module together with tied weights
			SCREAMING_SNAKE_CASE_   : Dict					  =      set(lowerCamelCase_  ) - set(lowerCamelCase_  )
			SCREAMING_SNAKE_CASE_   : List[str]					  =      list(set(lowerCamelCase_  )  ) + list(lowerCamelCase_  )

			# remove ".weight" from the keys
			SCREAMING_SNAKE_CASE_   : Optional[Any]					  =      ['.weight', '.bias']
			SCREAMING_SNAKE_CASE_   : str					  =      []
			for name in list_untouched:
						for name_to_remove in names_to_remove:
									if name_to_remove in name:
												SCREAMING_SNAKE_CASE_   : Union[str, Any]					  =      name.replace(lowerCamelCase_  ,							''  )
						filtered_module_names.append(lowerCamelCase_  )

			return filtered_module_names









from __future__ import annotations





def        __UpperCAmelCase						(							lowerCamelCase_ :     list[float]  )       ->  float:







			"""simple docstring"""





			SCREAMING_SNAKE_CASE_   : Tuple					  =      0.0_0
			SCREAMING_SNAKE_CASE_   : Tuple					  =      0
			for resistor in resistors:
						if resistor <= 0:
									SCREAMING_SNAKE_CASE_   : Optional[Any]					  =      F'Resistor at index {index} has a negative or zero value!'
									raise ValueError(lowerCamelCase_  )
						first_sum += 1 / float(lowerCamelCase_  )
						index += 1
			return 1 / first_sum





def        __UpperCAmelCase						(							lowerCamelCase_ :     list[float]  )       ->  float:







			"""simple docstring"""





			SCREAMING_SNAKE_CASE_   : Dict					  =      0.0_0
			SCREAMING_SNAKE_CASE_   : Union[str, Any]					  =      0
			for resistor in resistors:
						sum_r += resistor
						if resistor < 0:
									SCREAMING_SNAKE_CASE_   : Union[str, Any]					  =      F'Resistor at index {index} has a negative value!'
									raise ValueError(lowerCamelCase_  )
						index += 1
			return sum_r


if __name__ == "__main__":
						import doctest

						doctest.testmod()



