



"""simple docstring"""


import logging
import os

import quant_trainer
import torch
from torch.utils.data import DataLoader

from transformers import Trainer, is_torch_tpu_available
from transformers.trainer_utils import PredictionOutput


__A      :							int   =      logging.getLogger(__name__)

if is_torch_tpu_available(check_device=False):
					import torch_xla.core.xla_model as xm
					import torch_xla.debug.metrics as met
class 	_a       (    lowercase__):
			"""simple docstring"""



			def __init__(						self   :			int ,      *__UpperCamelCase   :			Any ,      __UpperCamelCase   :			List[str]=None ,      __UpperCamelCase   :			Union[str, Any]=None ,      __UpperCamelCase   :			Dict=None ,      **__UpperCamelCase   :			List[Any]      )->Union[str, Any]:
							super().__init__(*__lowerCamelCase ,      **__lowerCamelCase      )
							_UpperCAmelCase							=			eval_examples
							_UpperCAmelCase							=			post_process_function
							_UpperCAmelCase							=			quant_trainer_args
							_UpperCAmelCase							=			1_2_8  # default number of calibration samples



			def        lowercase__  (						self   :			Dict ,      __UpperCamelCase   :			Dict=None      )->Optional[Any]:



							if calib_dataset is None and self.calib_dataset is None:
											raise ValueError('''Trainer: calibration requires an calib_dataset.'''      )
							_UpperCAmelCase							=			calib_dataset if calib_dataset is not None else self.calib_dataset

							_UpperCAmelCase							=			self._remove_unused_columns(__lowerCamelCase ,      description='''Calibration'''      )

							return DataLoader(
							    __lowerCamelCase ,      batch_size=self.args.eval_batch_size ,      collate_fn=self.data_collator ,      drop_last=self.args.dataloader_drop_last ,      num_workers=self.args.dataloader_num_workers ,      pin_memory=self.args.dataloader_pin_memory ,      shuffle=__lowerCamelCase ,      )



			def        lowercase__  (						self   :			Dict ,      __UpperCamelCase   :			Optional[int]=None      )->int:
							_UpperCAmelCase							=			self.train_dataset if calib_dataset is None else calib_dataset
							_UpperCAmelCase							=			self.get_calib_dataloader(__lowerCamelCase      )

							_UpperCAmelCase							=			self.model
							quant_trainer.configure_model(__lowerCamelCase ,      self.quant_trainer_args ,      calib=__lowerCamelCase      )
							model.eval()
							quant_trainer.enable_calibration(__lowerCamelCase      )

							logger.info('''***** Running calibration *****'''      )
							logger.info(F'  Num examples = {self.calib_num}'      )
							logger.info(F'  Batch size = {calib_dataloader.batch_size}'      )

							for step, inputs in enumerate(__lowerCamelCase      ):
											# Prediction step
											_UpperCAmelCase							=			self.prediction_step(__lowerCamelCase ,      __lowerCamelCase ,      prediction_loss_only=__lowerCamelCase      )
											if (step + 1) * calib_dataloader.batch_size >= self.calib_num:
															break

							quant_trainer.finish_calibration(__lowerCamelCase ,      self.quant_trainer_args      )
							_UpperCAmelCase							=			model



			def        lowercase__  (						self   :			List[str] ,      __UpperCamelCase   :			Union[str, Any]=None ,      __UpperCamelCase   :			Union[str, Any]=None ,      __UpperCamelCase   :			Any=None ,      __UpperCamelCase   :			str = "eval"      )->int:
							_UpperCAmelCase							=			self.eval_dataset if eval_dataset is None else eval_dataset
							_UpperCAmelCase							=			self.get_eval_dataloader(__lowerCamelCase      )
							_UpperCAmelCase							=			self.eval_examples if eval_examples is None else eval_examples

							# Temporarily disable metric computation, we will do it in the loop here.
							_UpperCAmelCase							=			self.compute_metrics
							_UpperCAmelCase							=			None
							_UpperCAmelCase							=			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
							try:
											_UpperCAmelCase							=			eval_loop(
											    __lowerCamelCase ,      description='''Evaluation''' ,      prediction_loss_only=True if compute_metrics is None else None ,      ignore_keys=__lowerCamelCase ,      )
							finally:
											_UpperCAmelCase							=			compute_metrics

							if self.post_process_function is not None and self.compute_metrics is not None:
											_UpperCAmelCase							=			self.post_process_function(__lowerCamelCase ,      __lowerCamelCase ,      output.predictions      )
											_UpperCAmelCase							=			self.compute_metrics(__lowerCamelCase      )

											# Prefix all keys with metric_key_prefix + '_'
											for key in list(metrics.keys()      ):
															if not key.startswith(F'{metric_key_prefix}_'      ):
																			_UpperCAmelCase							=			metrics.pop(__lowerCamelCase      )

											self.log(__lowerCamelCase      )
							else:
											_UpperCAmelCase							=			{}

							if self.args.tpu_metrics_debug or self.args.debug:
											# tpu-comment: Logging debug metrics for PyTorch/XLA (compile, execute times, ops, etc.)
											xm.master_print(met.metrics_report()      )

							_UpperCAmelCase							=			self.callback_handler.on_evaluate(self.args ,      self.state ,      self.control ,      __lowerCamelCase      )
							return metrics



			def        lowercase__  (						self   :			Optional[int] ,      __UpperCamelCase   :			Optional[Any] ,      __UpperCamelCase   :			List[Any] ,      __UpperCamelCase   :			int=None ,      __UpperCamelCase   :			str = "test"      )->int:
							_UpperCAmelCase							=			self.get_test_dataloader(__lowerCamelCase      )

							# Temporarily disable metric computation, we will do it in the loop here.
							_UpperCAmelCase							=			self.compute_metrics
							_UpperCAmelCase							=			None
							_UpperCAmelCase							=			self.prediction_loop if self.args.use_legacy_prediction_loop else self.evaluation_loop
							try:
											_UpperCAmelCase							=			eval_loop(
											    __lowerCamelCase ,      description='''Prediction''' ,      prediction_loss_only=True if compute_metrics is None else None ,      ignore_keys=__lowerCamelCase ,      )
							finally:
											_UpperCAmelCase							=			compute_metrics

							if self.post_process_function is None or self.compute_metrics is None:
											return output

							_UpperCAmelCase							=			self.post_process_function(__lowerCamelCase ,      __lowerCamelCase ,      output.predictions ,      '''predict'''      )
							_UpperCAmelCase							=			self.compute_metrics(__lowerCamelCase      )

							# Prefix all keys with metric_key_prefix + '_'
							for key in list(metrics.keys()      ):
											if not key.startswith(F'{metric_key_prefix}_'      ):
															_UpperCAmelCase							=			metrics.pop(__lowerCamelCase      )

							return PredictionOutput(predictions=predictions.predictions ,      label_ids=predictions.label_ids ,      metrics=__lowerCamelCase      )



			def        lowercase__  (						self   :			Optional[int] ,      __UpperCamelCase   :			List[Any]="./"      )->Optional[int]:
							_UpperCAmelCase							=			self.eval_dataset
							_UpperCAmelCase							=			self.get_eval_dataloader(__lowerCamelCase      )

							_UpperCAmelCase							=			next(iter(__lowerCamelCase      )      )

							# saving device - to make it consistent
							_UpperCAmelCase							=			torch.device('''cuda''' if torch.cuda.is_available() else '''cpu'''      )

							# convert to tuple
							_UpperCAmelCase							=			tuple(v.to(__lowerCamelCase      ) for k, v in batch.items()      )

							logger.info('''Converting model to be onnx compatible'''      )
							from pytorch_quantization.nn import TensorQuantizer

							_UpperCAmelCase							=			True

							_UpperCAmelCase							=			self.model.to(__lowerCamelCase      )

							model.eval()
							model.float()

							_UpperCAmelCase							=			model.module if hasattr(__lowerCamelCase ,      '''module'''      ) else model
							quant_trainer.configure_model(__lowerCamelCase ,      self.quant_trainer_args      )

							_UpperCAmelCase							=			os.path.join(__lowerCamelCase ,      '''model.onnx'''      )
							logger.info(F'exporting model to {output_model_file}'      )

							_UpperCAmelCase							=			{0: "batch_size", 1: "seq_len"}

							torch.onnx.export(
							    __lowerCamelCase ,      __lowerCamelCase ,      __lowerCamelCase ,      export_params=__lowerCamelCase ,      opset_version=1_3 ,      do_constant_folding=__lowerCamelCase ,      input_names=['''input_ids''', '''attention_mask''', '''token_type_ids'''] ,      output_names=['''output_start_logits''', '''output_end_logits'''] ,      dynamic_axes={
							        '''input_ids''': axes,
							        '''attention_mask''': axes,
							        '''token_type_ids''': axes,
							        '''output_start_logits''': axes,
							        '''output_end_logits''': axes,
							    } ,      verbose=__lowerCamelCase ,      )
							logger.info('''onnx export finished'''      )







from __future__ import annotations

from typing import Any

def       lowercase_		(		_A			:    list[Any]						):

      """simple docstring"""




      create_state_space_tree(_A    ,					[]    ,					0						)

def       lowercase_		(		_A			:    list[Any]    ,					_A			:    list[Any]    ,					_A			:    int						):

      """simple docstring"""




      if index == len(_A						):
            print(_A						)
            return

      create_state_space_tree(_A    ,					_A    ,					index + 1						)
      current_subsequence.append(sequence[index]						)
      create_state_space_tree(_A    ,					_A    ,					index + 1						)
      current_subsequence.pop()


if __name__ == "__main__":
    A      :    list[Any]		=					[3, 1, 2, 4]
    generate_all_subsequences(seq)

    seq.clear()
    seq.extend(["A", "B", "C"])
    generate_all_subsequences(seq)


