





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

lowerCAmelCase     :   Dict						     =  logging.get_logger(__name__)

def    A_  (							a					,   a					,   a					,   a=None					,   a=None  ):

      """simple docstring"""



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

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

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

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

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

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

            if is_buffer:
                  SCREAMING_SNAKE_CASE_				:  Tuple           =     new_value
            else:
                  SCREAMING_SNAKE_CASE_				:  Optional[Any]           =     nn.Parameter(__UpperCamelCase					,   requires_grad=old_value.requires_grad  )
                  SCREAMING_SNAKE_CASE_				:  Union[str, Any]           =     new_value

def    A_  (							a					,   a=None					,   a=None					,   a=None					,   a=False  ):

      """simple docstring"""



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

                              if quantization_config.quantization_method() == "llm_int8":
                                    SCREAMING_SNAKE_CASE_				:  List[str]           =     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					,   )
                                    SCREAMING_SNAKE_CASE_				:  int           =     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_				:  Optional[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					,   )
                                          SCREAMING_SNAKE_CASE_				:  List[Any]           =     True
                    # Store the module class in case we need to transpose the weight later
                              SCREAMING_SNAKE_CASE_				:  List[Any]           =     type(__UpperCamelCase  )
                              # Force requires grad to False to avoid unexpected errors
                              model._modules[name].requires_grad_(__UpperCamelCase  )
            if len(list(module.children()  )  ) > 0:
                  SCREAMING_SNAKE_CASE_       ,						SCREAMING_SNAKE_CASE_				:  Dict           =     _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    A_  (							a					,   a=None					,   a=None					,   a=None  ):

      """simple docstring"""



      SCREAMING_SNAKE_CASE_				:  Any           =     ['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(
          __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    A_  (							*a					,   **a  ):

      """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    A_  (							*a					,   **a  ):

      """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    A_  (							a  ):

      """simple docstring"""



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

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

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

      # add last module together with tied weights
      SCREAMING_SNAKE_CASE_				:  int           =     set(__UpperCamelCase  ) - set(__UpperCamelCase  )
      SCREAMING_SNAKE_CASE_				:  Union[str, Any]           =     list(set(__UpperCamelCase  )  ) + list(__UpperCamelCase  )

      # remove ".weight" from the keys
      SCREAMING_SNAKE_CASE_				:  List[str]           =     ['.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_				:  str           =     name.replace(__UpperCamelCase					,   ''  )
            filtered_module_names.append(__UpperCamelCase  )

      return filtered_module_names









def    A_  (							a					,   a  ):

      """simple docstring"""



      return int((input_a, input_a).count(0  ) != 0  )

def    A_  (							):

      """simple docstring"""



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






