




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

UpperCAmelCase_ 		=      logging.get_logger(__name__)


def 						SCREAMING_SNAKE_CASE       (      a_	:							Dict				,					a_	:							str				,					a_	:							Optional[int]				,					a_	:							Optional[Any]=None				,					a_	:							Optional[Any]=None			):







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

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

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

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

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

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

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

    if is_buffer:
      __a			=					new_value
    else:
      __a			=					nn.Parameter(a_				,					requires_grad=old_value.requires_grad			)
      __a			=					new_value


def 						SCREAMING_SNAKE_CASE       (      a_	:							List[str]				,					a_	:							List[str]=None				,					a_	:							Tuple=None				,					a_	:							Optional[int]=None				,					a_	:							List[Any]=False			):







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

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

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


def 						SCREAMING_SNAKE_CASE       (      a_	:							Dict				,					a_	:							str=None				,					a_	:							str=None				,					a_	:							int=None			):
  __a			=					["lm_head"] if modules_to_not_convert is None else modules_to_not_convert
  __a			=					_replace_with_bnb_linear(
      a_				,					a_				,					a_				,					a_			)

  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 						SCREAMING_SNAKE_CASE       (      *a_	:							Dict				,					**a_	:							Dict			):
  warnings.warn(
      '`replace_8bit_linear` will be deprecated in a future version, please use `replace_with_bnb_linear` instead'				,					a_				,					)
  return replace_with_bnb_linear(*a_				,					**a_			)


def 						SCREAMING_SNAKE_CASE       (      *a_	:							Optional[Any]				,					**a_	:							Optional[Any]			):
  warnings.warn(
      '`set_module_8bit_tensor_to_device` will be deprecated in a future version, please use `set_module_quantized_tensor_to_device` instead'				,					a_				,					)
  return set_module_quantized_tensor_to_device(*a_				,					**a_			)


def 						SCREAMING_SNAKE_CASE       (      a_	:							Union[str, Any]			):
  __a			=					deepcopy(a_			)  # this has 0 cost since it is done inside `init_empty_weights` context manager`
  tied_model.tie_weights()

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

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

  # add last module together with tied weights
  __a			=					set(a_			) - set(a_			)
  __a			=					list(set(a_			)			) + list(a_			)

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

  return filtered_module_names









'''simple docstring'''


def 						SCREAMING_SNAKE_CASE       (      a_	:							int				,					a_	:							int			):
  return int((input_a, input_a).count(0			) != 0			)


def 						SCREAMING_SNAKE_CASE       (      ):
  assert nand_gate(0				,					0			) == 1
  assert nand_gate(0				,					1			) == 1
  assert nand_gate(1				,					0			) == 1
  assert nand_gate(1				,					1			) == 0


if __name__ == "__main__":
  print(nand_gate(0, 0))
  print(nand_gate(0, 1))
  print(nand_gate(1, 0))
  print(nand_gate(1, 1))



