



# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import importlib.metadata
import json
import os
from dataclasses import dataclass
from typing import Any, Dict, Union

from packaging import version

from ..utils import is_torch_available, logging


if is_torch_available():
						import torch


_snake_case						=    logging.get_logger(__name__)



@dataclass
class     UpperCAmelCase_       :







							def __init__(  self,     __a=False,     __a=False,     __a=6.0,     __a=None,     __a=False,     __a=False,     __a=None,     __a="fp4",     __a=False,     **__a,     ):

														'''simple docstring'''

														_lowerCAmelCase	:				Tuple					  =       load_in_abit
														_lowerCAmelCase	:				List[Any]					  =       load_in_abit
														_lowerCAmelCase	:				List[str]					  =       llm_inta_threshold
														_lowerCAmelCase	:				Any					  =       llm_inta_skip_modules
														_lowerCAmelCase	:				List[Any]					  =       llm_inta_enable_fpaa_cpu_offload
														_lowerCAmelCase	:				Tuple					  =       llm_inta_has_fpaa_weight
														_lowerCAmelCase	:				Dict					  =       bnb_abit_quant_type
														_lowerCAmelCase	:				int					  =       bnb_abit_use_double_quant

														if bnb_abit_compute_dtype is None:
																					_lowerCAmelCase	:				Any					  =       torch.floataa
														elif isinstance(__UpperCamelCase,     __UpperCamelCase):
																					_lowerCAmelCase	:				Union[str, Any]					  =       getattr(__UpperCamelCase,     __UpperCamelCase)
														elif isinstance(__UpperCamelCase,     torch.dtype):
																					_lowerCAmelCase	:				List[Any]					  =       bnb_abit_compute_dtype
														else:
																					raise ValueError("bnb_4bit_compute_dtype must be a string or a torch.dtype")

														self.post_init()







							def   snake_case__ (  self):

														'''simple docstring'''

														if not isinstance(self.llm_inta_threshold,     __UpperCamelCase):
																					raise ValueError("llm_int8_threshold must be a float")

														if self.llm_inta_skip_modules is not None and not isinstance(self.llm_inta_skip_modules,     __UpperCamelCase):
																					raise ValueError("llm_int8_skip_modules must be a list of strings")
														if not isinstance(self.llm_inta_enable_fpaa_cpu_offload,     __UpperCamelCase):
																					raise ValueError("llm_int8_enable_fp32_cpu_offload must be a boolean")

														if not isinstance(self.llm_inta_has_fpaa_weight,     __UpperCamelCase):
																					raise ValueError("llm_int8_has_fp16_weight must be a boolean")

														if self.bnb_abit_compute_dtype is not None and not isinstance(self.bnb_abit_compute_dtype,     torch.dtype):
																					raise ValueError("bnb_4bit_compute_dtype must be torch.dtype")

														if not isinstance(self.bnb_abit_quant_type,     __UpperCamelCase):
																					raise ValueError("bnb_4bit_quant_type must be a string")

														if not isinstance(self.bnb_abit_use_double_quant,     __UpperCamelCase):
																					raise ValueError("bnb_4bit_use_double_quant must be a boolean")

														if self.load_in_abit and not version.parse(importlib.metadata.version("bitsandbytes")) >= version.parse(
														    "0.39.0"):
																					raise ValueError(
																					    "4 bit quantization requires bitsandbytes>=0.39.0 - please upgrade your bitsandbytes version")







							def   snake_case__ (  self):

														'''simple docstring'''

														return self.load_in_abit or self.load_in_abit







							def   snake_case__ (  self):

														'''simple docstring'''

														if self.load_in_abit:
																					return "llm_int8"
														elif self.load_in_abit and self.bnb_abit_quant_type == "fp4":
																					return "fp4"
														elif self.load_in_abit and self.bnb_abit_quant_type == "nf4":
																					return "nf4"
														else:
																					return None







							@classmethod
							def   snake_case__ (  cls,     __a,     __a,     **__a):

														'''simple docstring'''

														_lowerCAmelCase	:				str					  =       cls(**__UpperCamelCase)

														_lowerCAmelCase	:				Any					  =       []
														for key, value in kwargs.items():
																					if hasattr(__UpperCamelCase,     __UpperCamelCase):
																												setattr(__UpperCamelCase,     __UpperCamelCase,     __UpperCamelCase)
																												to_remove.append(__UpperCamelCase)
														for key in to_remove:
																					kwargs.pop(__UpperCamelCase,     __UpperCamelCase)

														if return_unused_kwargs:
																					return config, kwargs
														else:
																					return config







							def   snake_case__ (  self,     __a):

														'''simple docstring'''

														with open(__UpperCamelCase,     "w",     encoding="utf-8") as writer:
																					_lowerCAmelCase	:				Dict					  =       self.to_dict()
																					_lowerCAmelCase	:				Any					  =       json.dumps(__UpperCamelCase,     indent=2,     sort_keys=__UpperCamelCase) + "\n"

																					writer.write(__UpperCamelCase)







							def   snake_case__ (  self):

														'''simple docstring'''

														_lowerCAmelCase	:				Optional[Any]					  =       copy.deepcopy(self.__dict__)
														_lowerCAmelCase	:				Any					  =       str(output["bnb_4bit_compute_dtype"]).split(".")[1]

														return output







							def __repr__(  self):

														'''simple docstring'''

														return f"{self.__class__.__name__} {self.to_json_string()}"







							def   snake_case__ (  self,     __a = True):

														'''simple docstring'''

														if use_diff is True:
																					_lowerCAmelCase	:				Optional[int]					  =       self.to_diff_dict()
														else:
																					_lowerCAmelCase	:				int					  =       self.to_dict()
														return json.dumps(__UpperCamelCase,     indent=2,     sort_keys=__UpperCamelCase) + "\n"







							def   snake_case__ (  self):

														'''simple docstring'''

														_lowerCAmelCase	:				Tuple					  =       self.to_dict()

														# get the default config dict
														_lowerCAmelCase	:				Optional[int]					  =       BitsAndBytesConfig().to_dict()

														_lowerCAmelCase	:				Optional[int]					  =       {}

														# only serialize values that differ from the default config
														for key, value in config_dict.items():
																					if value != default_config_dict[key]:
																												_lowerCAmelCase	:				Tuple					  =       value

														return serializable_config_dict








import unittest

from transformers import is_torch_available
from transformers.testing_utils import require_torch


if is_torch_available():
 import torch

 from transformers.generation import DisjunctiveConstraint



@require_torch
class 				_UpperCamelCase      (unittest.TestCase      ):


      def 			__UpperCAmelCase		(						self						)->						List[Any]:
           # For consistency across different places the DisjunctiveConstraint is called,
           # dc.token_ids is a list of integers. It is also initialized only by integers.

           __lowerCAmelCase             =       [[1, 2, 4], [1, 2, 3, 4]]
           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)
           self.assertTrue(isinstance(dc.token_ids       ,    __UpperCamelCase						)						)

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint(torch.LongTensor([[1, 2, 4], [1, 2, 3]]						)						)

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint([torch.LongTensor([1, 2, 4]						), torch.LongTensor([1, 2, 3, 4, 5]						)]						)


      def 			__UpperCAmelCase		(						self						)->						Tuple:
           # We can't have constraints that are complete subsets of another. This leads to a preverse
           # interpretation of "constraint fulfillment": does generating [1,2,3] fulfill the constraint?
           # It would mean that it generated [1,2] which fulfills it, but it's in the middle of potentially
           # fulfilling [1,2,3,4]. If we believe that [1,2,3] does fulfill the constraint, then the algorithm
           # will necessarily never reach [1,2,3,4], giving users a false sense of control (better to just not allow it).
           __lowerCAmelCase             =       [[1, 2], [1, 2, 3, 4]]

           with self.assertRaises(__UpperCamelCase						):
                DisjunctiveConstraint(__UpperCamelCase						)  # fails here


      def 			__UpperCAmelCase		(						self						)->						List[Any]:
           __lowerCAmelCase             =       [[1, 2, 3], [1, 2, 4]]

           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           __lowerCAmelCase             =       stepped is True and completed is False and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           __lowerCAmelCase             =       stepped is True and completed is False and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(3						)
           __lowerCAmelCase             =       stepped is True and completed is True and reset is False
           self.assertTrue(__UpperCamelCase						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.current_seq == [1, 2, 3]						)


      def 			__UpperCAmelCase		(						self						)->						int:
           __lowerCAmelCase             =       [[1, 2, 3], [1, 2, 4, 5], [1, 2, 5]]

           __lowerCAmelCase             =       DisjunctiveConstraint(__UpperCamelCase						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(4						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.current_seq == [1, 2, 4]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(5						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.current_seq == [1, 2, 4, 5]						)

           dc.reset()

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(1						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.remaining() == 3						)
           self.assertTrue(dc.current_seq == [1]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(2						)
           self.assertTrue(not dc.completed						)
           self.assertTrue(dc.remaining() == 2						)
           self.assertTrue(dc.current_seq == [1, 2]						)

           __lowerCAmelCase      ,			__lowerCAmelCase      ,			__lowerCAmelCase             =       dc.update(5						)
           self.assertTrue(dc.completed						)  # Completed!
           self.assertTrue(dc.remaining() == 0						)
           self.assertTrue(dc.current_seq == [1, 2, 5]						)






