




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__     :     List[str]		    =       logging.get_logger(__name__)

def lowercase    (  SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=None )			->							int:


			'''simple docstring'''







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

			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_								=						False
			SCREAMING_SNAKE_CASE_								=						False
			if is_buffer or not is_bitsandbytes_available():
						SCREAMING_SNAKE_CASE_								=						False
						SCREAMING_SNAKE_CASE_								=						False
			else:
						SCREAMING_SNAKE_CASE_								=						hasattr(bnb.nn       ,    'Params4bit' ) and isinstance(module._parameters[tensor_name]       ,    bnb.nn.Paramsabit )
						SCREAMING_SNAKE_CASE_								=						isinstance(module._parameters[tensor_name]       ,    bnb.nn.IntaParams )

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

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

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

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

						if is_buffer:
									SCREAMING_SNAKE_CASE_								=						new_value
						else:
									SCREAMING_SNAKE_CASE_								=						nn.Parameter(SCREAMING_SNAKE_CASE       ,    requires_grad=old_value.requires_grad )
									SCREAMING_SNAKE_CASE_								=						new_value

def lowercase    (  SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=False )			->							Optional[Any]:


			'''simple docstring'''







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

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

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

def lowercase    (  SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=None       ,    SCREAMING_SNAKE_CASE=None )			->							Tuple:


			'''simple docstring'''







			SCREAMING_SNAKE_CASE_								=						['lm_head'] if modules_to_not_convert is None else modules_to_not_convert
			SCREAMING_SNAKE_CASE_						,		SCREAMING_SNAKE_CASE_								=						_replace_with_bnb_linear(
			    SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE       ,    SCREAMING_SNAKE_CASE )

			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 lowercase    (  *SCREAMING_SNAKE_CASE       ,    **SCREAMING_SNAKE_CASE )			->							Any:


			'''simple docstring'''







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

def lowercase    (  *SCREAMING_SNAKE_CASE       ,    **SCREAMING_SNAKE_CASE )			->							List[str]:


			'''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'       ,    SCREAMING_SNAKE_CASE       ,    )
			return set_module_quantized_tensor_to_device(*SCREAMING_SNAKE_CASE       ,    **SCREAMING_SNAKE_CASE )

def lowercase    (  SCREAMING_SNAKE_CASE )			->							List[str]:


			'''simple docstring'''







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

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

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

			# add last module together with tied weights
			SCREAMING_SNAKE_CASE_								=						set(SCREAMING_SNAKE_CASE ) - set(SCREAMING_SNAKE_CASE )
			SCREAMING_SNAKE_CASE_								=						list(set(SCREAMING_SNAKE_CASE ) ) + list(SCREAMING_SNAKE_CASE )

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

			return filtered_module_names






from __future__ import annotations

from decimal import Decimal

from numpy import array

def lowercase    (  SCREAMING_SNAKE_CASE )			->							list[list[float]]:


			'''simple docstring'''







			SCREAMING_SNAKE_CASE_								=						Decimal

			# Check if the provided matrix has 2 rows and 2 columns
			# since this implementation only works for 2x2 matrices
			if len(SCREAMING_SNAKE_CASE ) == 2 and len(matrix[0] ) == 2 and len(matrix[1] ) == 2:
						# Calculate the determinant of the matrix
						SCREAMING_SNAKE_CASE_								=						float(
						    d(matrix[0][0] ) * d(matrix[1][1] ) - d(matrix[1][0] ) * d(matrix[0][1] ) )
						if determinant == 0:
									raise ValueError('This matrix has no inverse.' )

						# Creates a copy of the matrix with swapped positions of the elements
						SCREAMING_SNAKE_CASE_								=						[[0.0, 0.0], [0.0, 0.0]]
						SCREAMING_SNAKE_CASE_						,		SCREAMING_SNAKE_CASE_								=						matrix[1][1], matrix[0][0]
						SCREAMING_SNAKE_CASE_						,		SCREAMING_SNAKE_CASE_								=						-matrix[1][0], -matrix[0][1]

						# Calculate the inverse of the matrix
						return [
						    [(float(d(SCREAMING_SNAKE_CASE ) ) / determinant) or 0.0 for n in row] for row in swapped_matrix
						]
			elif (
			    len(SCREAMING_SNAKE_CASE ) == 3
			    and len(matrix[0] ) == 3
			    and len(matrix[1] ) == 3
			    and len(matrix[2] ) == 3
			):
						# Calculate the determinant of the matrix using Sarrus rule
						SCREAMING_SNAKE_CASE_								=						float(
						    (
						        (d(matrix[0][0] ) * d(matrix[1][1] ) * d(matrix[2][2] ))
						        + (d(matrix[0][1] ) * d(matrix[1][2] ) * d(matrix[2][0] ))
						        + (d(matrix[0][2] ) * d(matrix[1][0] ) * d(matrix[2][1] ))
						    )
						    - (
						        (d(matrix[0][2] ) * d(matrix[1][1] ) * d(matrix[2][0] ))
						        + (d(matrix[0][1] ) * d(matrix[1][0] ) * d(matrix[2][2] ))
						        + (d(matrix[0][0] ) * d(matrix[1][2] ) * d(matrix[2][1] ))
						    ) )
						if determinant == 0:
									raise ValueError('This matrix has no inverse.' )

						# Creating cofactor matrix
						SCREAMING_SNAKE_CASE_								=						[
						    [d(0.0 ), d(0.0 ), d(0.0 )],
						    [d(0.0 ), d(0.0 ), d(0.0 )],
						    [d(0.0 ), d(0.0 ), d(0.0 )],
						]
						SCREAMING_SNAKE_CASE_								=						(d(matrix[1][1] ) * d(matrix[2][2] )) - (
						    d(matrix[1][2] ) * d(matrix[2][1] )
						)
						SCREAMING_SNAKE_CASE_								=						-(
						    (d(matrix[1][0] ) * d(matrix[2][2] )) - (d(matrix[1][2] ) * d(matrix[2][0] ))
						)
						SCREAMING_SNAKE_CASE_								=						(d(matrix[1][0] ) * d(matrix[2][1] )) - (
						    d(matrix[1][1] ) * d(matrix[2][0] )
						)
						SCREAMING_SNAKE_CASE_								=						-(
						    (d(matrix[0][1] ) * d(matrix[2][2] )) - (d(matrix[0][2] ) * d(matrix[2][1] ))
						)
						SCREAMING_SNAKE_CASE_								=						(d(matrix[0][0] ) * d(matrix[2][2] )) - (
						    d(matrix[0][2] ) * d(matrix[2][0] )
						)
						SCREAMING_SNAKE_CASE_								=						-(
						    (d(matrix[0][0] ) * d(matrix[2][1] )) - (d(matrix[0][1] ) * d(matrix[2][0] ))
						)
						SCREAMING_SNAKE_CASE_								=						(d(matrix[0][1] ) * d(matrix[1][2] )) - (
						    d(matrix[0][2] ) * d(matrix[1][1] )
						)
						SCREAMING_SNAKE_CASE_								=						-(
						    (d(matrix[0][0] ) * d(matrix[1][2] )) - (d(matrix[0][2] ) * d(matrix[1][0] ))
						)
						SCREAMING_SNAKE_CASE_								=						(d(matrix[0][0] ) * d(matrix[1][1] )) - (
						    d(matrix[0][1] ) * d(matrix[1][0] )
						)

						# Transpose the cofactor matrix (Adjoint matrix)
						SCREAMING_SNAKE_CASE_								=						array(SCREAMING_SNAKE_CASE )
						for i in range(3 ):
									for j in range(3 ):
												SCREAMING_SNAKE_CASE_								=						cofactor_matrix[j][i]

        # Inverse of the matrix using the formula (1/determinant) * adjoint matrix
						SCREAMING_SNAKE_CASE_								=						array(SCREAMING_SNAKE_CASE )
						for i in range(3 ):
									for j in range(3 ):
												inverse_matrix[i][j] /= d(SCREAMING_SNAKE_CASE )

        # Calculate the inverse of the matrix
						return [[float(d(SCREAMING_SNAKE_CASE ) ) or 0.0 for n in row] for row in inverse_matrix]
			raise ValueError('Please provide a matrix of size 2x2 or 3x3.' )
