




'''simple docstring'''






import logging
import re

import pytorch_quantization
import pytorch_quantization.nn as quant_nn
import torch
from pytorch_quantization import calib
from pytorch_quantization.tensor_quant import QuantDescriptor


A_			      =		logging.getLogger(__name__)

A_			      =		50  # max width of layer names
A_			      =		70  # max width of quantizer names






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   List[Any]:
      snake_case__       :   Optional[int]	      =    parser.add_argument_group('quant_trainer arguments'		)
      group.add_argument('--wprec'				,      type=__lowerCAmelCase				,      default=8				,      help='weight precision'		)
      group.add_argument('--aprec'				,      type=__lowerCAmelCase				,      default=8				,      help='activation precision'		)
      group.add_argument('--quant-per-tensor'				,      action='store_true'				,      help='per tensor weight scaling'		)
      group.add_argument('--quant-disable'				,      action='store_true'				,      help='disable all quantizers'		)
      group.add_argument('--quant-disable-embeddings'				,      action='store_true'				,      help='disable all embeddings quantizers'		)
      group.add_argument('--quant-disable-keyword'				,      type=__lowerCAmelCase				,      nargs='+'				,      help='disable quantizers by keyword'		)
      group.add_argument('--quant-disable-layer-module'				,      type=__lowerCAmelCase				,      help='disable quantizers by keyword under layer.'		)
      group.add_argument('--quant-enable-layer-module'				,      type=__lowerCAmelCase				,      help='enable quantizers by keyword under layer'		)
      group.add_argument('--calibrator'				,      default='max'				,      help='which quantization range calibrator to use'		)
      group.add_argument('--percentile'				,      default=__lowerCAmelCase				,      type=__lowerCAmelCase				,      help='percentile for PercentileCalibrator'		)
      group.add_argument('--fuse-qkv'				,      action='store_true'				,      help='use the same scale factor for qkv'		)
      group.add_argument('--clip-gelu'				,      metavar='N'				,      type=__lowerCAmelCase				,      help='clip gelu output maximum value to N'		)
      group.add_argument(
          '--recalibrate-weights'				,      action='store_true'				,      help=(
              'recalibrate weight amaxes by taking the max of the weights.'
              ' amaxes will be computed with the current quantization granularity (axis).'
          )				,      )






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   Optional[Any]:

      if args.calibrator == "max":
            snake_case__       :   Dict	      =    'max'
      elif args.calibrator == "percentile":
            if args.percentile is None:
                  raise ValueError('Specify --percentile when using percentile calibrator'		)
            snake_case__       :   List[Any]	      =    'histogram'
      elif args.calibrator == "mse":
            snake_case__       :   Tuple	      =    'histogram'
      else:
            raise ValueError(f"Invalid calibrator {args.calibrator}"		)

      snake_case__       :   Optional[int]	      =    QuantDescriptor(num_bits=args.aprec				,      calib_method=__lowerCAmelCase		)
      snake_case__       :   Tuple	      =    QuantDescriptor(num_bits=args.wprec				,      axis=(None if args.quant_per_tensor else (0,))		)
      quant_nn.QuantLinear.set_default_quant_desc_input(__lowerCAmelCase		)
      quant_nn.QuantLinear.set_default_quant_desc_weight(__lowerCAmelCase		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE=False				,      __SCREAMING_SNAKE_CASE=False		)    ->   List[str]:
      logger.info('Configuring Model for Quantization'		)
      logger.info(f"using quantization package {pytorch_quantization.__file__}"		)

      if not calib:
            if args.quant_disable_embeddings:
                  set_quantizer_by_name(__lowerCAmelCase				,      ['embeddings']				,      which='weight'				,      _disabled=__lowerCAmelCase		)

            if args.quant_disable:
                  set_quantizer_by_name(__lowerCAmelCase				,      ['']				,      _disabled=__lowerCAmelCase		)

            if args.quant_disable_keyword:
                  set_quantizer_by_name(__lowerCAmelCase				,      args.quant_disable_keyword				,      _disabled=__lowerCAmelCase		)

            if args.quant_disable_layer_module:
                  set_quantizer_by_name(__lowerCAmelCase				,      [r'layer.\d+.' + args.quant_disable_layer_module]				,      _disabled=__lowerCAmelCase		)

            if args.quant_enable_layer_module:
                  set_quantizer_by_name(__lowerCAmelCase				,      [r'layer.\d+.' + args.quant_enable_layer_module]				,      _disabled=__lowerCAmelCase		)

            if args.recalibrate_weights:
                  recalibrate_weights(__lowerCAmelCase		)

            if args.fuse_qkv:
                  fuse_qkv(__lowerCAmelCase				,      __lowerCAmelCase		)

      if args.clip_gelu:
            clip_gelu(__lowerCAmelCase				,      args.clip_gelu		)

      # if args.local_rank in [-1, 0] and not calib:
      print_quant_summary(__lowerCAmelCase		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   List[str]:
      logger.info('Enabling Calibration'		)
      for name, module in model.named_modules():
            if name.endswith('_quantizer'		):
                  if module._calibrator is not None:
                        module.disable_quant()
                        module.enable_calib()
                  else:
                        module.disable()
                  logger.info(f"{name:80}: {module}"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE		)    ->   Optional[Any]:
      logger.info('Loading calibrated amax'		)
      for name, module in model.named_modules():
            if name.endswith('_quantizer'		):
                  if module._calibrator is not None:
                        if isinstance(module._calibrator				,      calib.MaxCalibrator		):
                              module.load_calib_amax()
                        else:
                              module.load_calib_amax('percentile'				,      percentile=args.percentile		)
                        module.enable_quant()
                        module.disable_calib()
                  else:
                        module.enable()
      model.cuda()
      print_quant_summary(__lowerCAmelCase		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE		)    ->   Optional[Any]:

      def fusea(__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE		):
            for mod in [qq, qk, qv]:
                  if not hasattr(__lowerCAmelCase				,      '_amax'		):
                        print('          WARNING: NO AMAX BUFFER'		)
                        return
            snake_case__       :   Union[str, Any]	      =    qq._amax.detach().item()
            snake_case__       :   str	      =    qk._amax.detach().item()
            snake_case__       :   str	      =    qv._amax.detach().item()

            snake_case__       :   Dict	      =    max(__lowerCAmelCase				,      __lowerCAmelCase				,      __lowerCAmelCase		)
            qq._amax.fill_(__lowerCAmelCase		)
            qk._amax.fill_(__lowerCAmelCase		)
            qv._amax.fill_(__lowerCAmelCase		)
            logger.info(f"          q={q:5.2f} k={k:5.2f} v={v:5.2f} -> {amax:5.2f}"		)

      for name, mod in model.named_modules():
            if name.endswith('.attention.self'		):
                  logger.info(f"FUSE_QKV: {name:{name_width}}"		)
                  fusea(mod.matmul_q_input_quantizer				,      mod.matmul_k_input_quantizer				,      mod.matmul_v_input_quantizer		)
                  if args.quant_per_tensor:
                        fusea(mod.query._weight_quantizer				,      mod.key._weight_quantizer				,      mod.value._weight_quantizer		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE		)    ->   Optional[int]:

      for name, mod in model.named_modules():
            if name.endswith('.output.dense'		) and not name.endswith('attention.output.dense'		):
                  snake_case__       :   Dict	      =    mod._input_quantizer._amax.data.detach().item()
                  mod._input_quantizer._amax.data.detach().clamp_(max=__lowerCAmelCase		)
                  snake_case__       :   Union[str, Any]	      =    mod._input_quantizer._amax.data.detach().item()
                  logger.info(f"CLIP_GELU: {name:{name_width}} amax: {amax_init:5.2f} -> {amax:5.2f}"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   Union[str, Any]:

      for name, mod in model.named_modules():
            if hasattr(__lowerCAmelCase				,      '_weight_quantizer'		) and mod._weight_quantizer.axis is not None:
                  snake_case__       :   str	      =    mod.weight.shape[0]
                  snake_case__       :   int	      =    mod._weight_quantizer._amax.detach()
                  snake_case__       :   List[str]	      =    torch.ones(__lowerCAmelCase				,      dtype=amax.dtype				,      device=amax.device		) * amax
                  print(f"expanding {name} {amax} -> {mod._weight_quantizer._amax}"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   Dict:

      for name, mod in model.named_modules():
            if hasattr(__lowerCAmelCase				,      '_weight_quantizer'		):
                  if not hasattr(mod.weight_quantizer				,      '_amax'		):
                        print('RECALIB: {name:{name_width}} WARNING: NO AMAX BUFFER'		)
                        continue

                  # determine which axes to reduce across
                  # e.g. a 4D tensor quantized per axis 0 should reduce over (1,2,3)
                  snake_case__       :   Union[str, Any]	      =    set() if mod._weight_quantizer.axis is None else set(mod._weight_quantizer.axis		)
                  snake_case__       :   str	      =    set(range(len(mod.weight.size()		)		)		) - axis_set
                  snake_case__       :   List[str]	      =    pytorch_quantization.utils.reduce_amax(mod.weight				,      axis=__lowerCAmelCase				,      keepdims=__lowerCAmelCase		).detach()
                  logger.info(f"RECALIB: {name:{name_width}} {mod._weight_quantizer._amax.flatten()} -> {amax.flatten()}"		)
                  snake_case__       :   Any	      =    amax






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE=25				,      __SCREAMING_SNAKE_CASE=180				,      __SCREAMING_SNAKE_CASE=None		)    ->   List[Any]:

      if ignore is None:
            snake_case__       :   List[str]	      =    []
      elif not isinstance(__lowerCAmelCase				,      __lowerCAmelCase		):
            snake_case__       :   int	      =    [ignore]

      snake_case__       :   Any	      =    0
      for name, mod in model.named_modules():
            if not hasattr(__lowerCAmelCase				,      'weight'		):
                  continue
            snake_case__       :   Any	      =    max(__lowerCAmelCase				,      len(__lowerCAmelCase		)		)

      for name, mod in model.named_modules():
            snake_case__       :   Any	      =    getattr(__lowerCAmelCase				,      '_input_quantizer'				,      __lowerCAmelCase		)
            snake_case__       :   Any	      =    getattr(__lowerCAmelCase				,      '_weight_quantizer'				,      __lowerCAmelCase		)
            if not hasattr(__lowerCAmelCase				,      'weight'		):
                  continue
            if type(__lowerCAmelCase		) in ignore:
                  continue
            if [True for s in ignore if type(__lowerCAmelCase		) is str and s in name]:
                  continue
            snake_case__       :   List[str]	      =    f"Act:{input_q.extra_repr()}"
            snake_case__       :   Any	      =    f"Wgt:{weight_q.extra_repr()}"
            snake_case__       :   Tuple	      =    f"{name:{name_width}} {act_str} {wgt_str}"
            if len(__lowerCAmelCase		) <= line_width:
                  logger.info(__lowerCAmelCase		)
            else:
                  logger.info(f"{name:{name_width}} {act_str}"		)
                  logger.info(f"{'  ':{name_width}} {wgt_str}"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE		)    ->   Dict:
      snake_case__       :   str	      =    0
      for name, mod in model.named_modules():
            if isinstance(__lowerCAmelCase				,      pytorch_quantization.nn.TensorQuantizer		):
                  print(f"{name:80} {mod}"		)
                  count += 1
      print(f"{count} TensorQuantizers found in model"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE		)    ->   Union[str, Any]:
      snake_case__       :   Union[str, Any]	      =    getattr(__lowerCAmelCase				,      __lowerCAmelCase				,      __lowerCAmelCase		)
      if quantizer_mod is not None:
            assert hasattr(__lowerCAmelCase				,      __lowerCAmelCase		)
            setattr(__lowerCAmelCase				,      __lowerCAmelCase				,      __lowerCAmelCase		)
      else:
            logger.warning(f"{name} has no {quantizer}"		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE="both"				,      **__SCREAMING_SNAKE_CASE		)    ->   Any:
      snake_case__       :   Tuple	      =    f"Warning: changing {which} quantizers of {name:{qname_width}}"
      for k, v in kwargs.items():
            s += f" {k}={v}"
            if which in ["input", "both"]:
                  set_quantizer(__lowerCAmelCase				,      __lowerCAmelCase				,      '_input_quantizer'				,      __lowerCAmelCase				,      __lowerCAmelCase		)
            if which in ["weight", "both"]:
                  set_quantizer(__lowerCAmelCase				,      __lowerCAmelCase				,      '_weight_quantizer'				,      __lowerCAmelCase				,      __lowerCAmelCase		)
      logger.info(__lowerCAmelCase		)






def 		UpperCamelCase__      (		__SCREAMING_SNAKE_CASE				,      __SCREAMING_SNAKE_CASE				,      **__SCREAMING_SNAKE_CASE		)    ->   Optional[int]:

      for name, mod in model.named_modules():
            if hasattr(__lowerCAmelCase				,      '_input_quantizer'		) or hasattr(__lowerCAmelCase				,      '_weight_quantizer'		):
                  for n in names:
                        if re.search(__lowerCAmelCase				,      __lowerCAmelCase		):
                              set_quantizers(__lowerCAmelCase				,      __lowerCAmelCase				,      **__lowerCAmelCase		)
            elif name.endswith('_quantizer'		):
                  for n in names:
                        if re.search(__lowerCAmelCase				,      __lowerCAmelCase		):
                              snake_case__       :   int	      =    f"Warning: changing {name:{name_width}}"
                              for k, v in kwargs.items():
                                    s += f" {k}={v}"
                                    setattr(__lowerCAmelCase				,      __lowerCAmelCase				,      __lowerCAmelCase		)
                              logger.info(__lowerCAmelCase		)





import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.metrics import mean_absolute_error, mean_squared_error
from sklearn.model_selection import train_test_split
from xgboost import XGBRegressor

def        __a			(   __lowerCAmelCase   )     ->     tuple:
					return (data["data"], data["target"])

def        __a			(   __lowerCAmelCase      ,	__lowerCAmelCase      ,	__lowerCAmelCase   )     ->     np.ndarray:
					SCREAMING_SNAKE_CASE							:     int						=				XGBRegressor(verbosity=0      ,	random_state=42   )
					xgb.fit(__lowerCAmelCase      ,	__lowerCAmelCase   )
					# Predict target for test data
					SCREAMING_SNAKE_CASE							:     List[Any]						=				xgb.predict(__lowerCAmelCase   )
					SCREAMING_SNAKE_CASE							:     str						=				predictions.reshape(len(__lowerCAmelCase   )      ,	1   )
					return predictions

def        __a			(   )     ->     None:
					SCREAMING_SNAKE_CASE							:     Dict						=				fetch_california_housing()
					SCREAMING_SNAKE_CASE					,  SCREAMING_SNAKE_CASE							:     Any						=				data_handling(__lowerCAmelCase   )
					SCREAMING_SNAKE_CASE					,  SCREAMING_SNAKE_CASE					,  SCREAMING_SNAKE_CASE					,  SCREAMING_SNAKE_CASE							:     str						=				train_test_split(
					    __lowerCAmelCase      ,	__lowerCAmelCase      ,	test_size=0.25      ,	random_state=1   )
					SCREAMING_SNAKE_CASE							:     int						=				xgboost(__lowerCAmelCase      ,	__lowerCAmelCase      ,	__lowerCAmelCase   )
					# Error printing
					print(F'''Mean Absolute Error : {mean_absolute_error(__lowerCAmelCase      ,	__lowerCAmelCase   )}'''   )
					print(F'''Mean Square Error  : {mean_squared_error(__lowerCAmelCase      ,	__lowerCAmelCase   )}'''   )


if __name__ == "__main__":
			import doctest

			doctest.testmod(verbose=True)
			main()