



'''simple docstring'''





import argparse
import glob
import logging
import os
import time
from argparse import Namespace

import numpy as np
import torch
from lightning_base import BaseTransformer, add_generic_args, generic_train
from torch.utils.data import DataLoader, TensorDataset

from transformers import glue_compute_metrics as compute_metrics
from transformers import glue_convert_examples_to_features as convert_examples_to_features
from transformers import glue_output_modes, glue_tasks_num_labels
from transformers import glue_processors as processors


_lowerCAmelCase      						=	logging.getLogger(__name__)






class        lowerCAmelCase_(				SCREAMING_SNAKE_CASE_     ):
  '''simple docstring'''




  __lowercase							:      Dict				=      '''sequence-classification'''




  def __init__(    self  ,__UpperCAmelCase      )    ->		Dict:
      if type(__UpperCAmelCase      ) == dict:
          lowerCAmelCase__ :  Optional[Any]							      =					Namespace(**__UpperCAmelCase      )
      lowerCAmelCase__ :  Union[str, Any]							      =					glue_output_modes[hparams.task]
      lowerCAmelCase__ :  Any							      =					glue_tasks_num_labels[hparams.task]

      super().__init__(__UpperCAmelCase  ,__UpperCAmelCase  ,self.mode      )




  def 							UpperCAmelCase_	(    self  ,**__UpperCAmelCase      )    ->		Union[str, Any]:
      return self.model(**__UpperCAmelCase      )




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase  ,__UpperCAmelCase      )    ->		Dict:
      lowerCAmelCase__ :  Union[str, Any]							      =					{"""input_ids""": batch[0], """attention_mask""": batch[1], """labels""": batch[3]}

      if self.config.model_type not in ["distilbert", "bart"]:
          lowerCAmelCase__ :  List[str]							      =					batch[2] if self.config.model_type in ["""bert""", """xlnet""", """albert"""] else None

      lowerCAmelCase__ :  Optional[Any]							      =					self(**__UpperCAmelCase      )
      lowerCAmelCase__ :  List[Any]							      =					outputs[0]

      lowerCAmelCase__ :  Dict							      =					self.trainer.lr_schedulers[0]["""scheduler"""]
      lowerCAmelCase__ :  List[Any]							      =					{"""loss""": loss, """rate""": lr_scheduler.get_last_lr()[-1]}
      return {"loss": loss, "log": tensorboard_logs}




  def 							UpperCAmelCase_	(    self      )    ->		List[str]:
      lowerCAmelCase__ :  Any							      =					self.hparams
      lowerCAmelCase__ :  List[str]							      =					processors[args.task]()
      lowerCAmelCase__ :  str							      =					processor.get_labels()

      for mode in ["train", "dev"]:
          lowerCAmelCase__ :  Tuple							      =					self._feature_file(__UpperCAmelCase      )
          if os.path.exists(__UpperCAmelCase      ) and not args.overwrite_cache:
              logger.info("""Loading features from cached file %s"""  ,__UpperCAmelCase      )
          else:
              logger.info("""Creating features from dataset file at %s"""  ,args.data_dir      )
              lowerCAmelCase__ :  List[Any]							      =					(
                  processor.get_dev_examples(args.data_dir      )
                  if mode == """dev"""
                  else processor.get_train_examples(args.data_dir      )
              )
              lowerCAmelCase__ :  Optional[Any]							      =					convert_examples_to_features(
                  __UpperCAmelCase  ,self.tokenizer  ,max_length=args.max_seq_length  ,label_list=self.labels  ,output_mode=args.glue_output_mode  ,)
              logger.info("""Saving features into cached file %s"""  ,__UpperCAmelCase      )
              torch.save(__UpperCAmelCase  ,__UpperCAmelCase      )




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase  ,__UpperCAmelCase  ,__UpperCAmelCase = False      )    ->		DataLoader:
      lowerCAmelCase__ :  Optional[int]							      =					"""dev""" if mode == """test""" else mode

      lowerCAmelCase__ :  Optional[int]							      =					self._feature_file(__UpperCAmelCase      )
      logger.info("""Loading features from cached file %s"""  ,__UpperCAmelCase      )
      lowerCAmelCase__ :  Tuple							      =					torch.load(__UpperCAmelCase      )
      lowerCAmelCase__ :  str							      =					torch.tensor([f.input_ids for f in features]  ,dtype=torch.long      )
      lowerCAmelCase__ :  str							      =					torch.tensor([f.attention_mask for f in features]  ,dtype=torch.long      )
      lowerCAmelCase__ :  List[str]							      =					torch.tensor([f.token_type_ids for f in features]  ,dtype=torch.long      )
      if self.hparams.glue_output_mode == "classification":
          lowerCAmelCase__ :  Optional[int]							      =					torch.tensor([f.label for f in features]  ,dtype=torch.long      )
      elif self.hparams.glue_output_mode == "regression":
          lowerCAmelCase__ :  Any							      =					torch.tensor([f.label for f in features]  ,dtype=torch.float      )

      return DataLoader(
          TensorDataset(__UpperCAmelCase  ,__UpperCAmelCase  ,__UpperCAmelCase  ,__UpperCAmelCase      )  ,batch_size=__UpperCAmelCase  ,shuffle=__UpperCAmelCase  ,)




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase  ,__UpperCAmelCase      )    ->		Any:
      lowerCAmelCase__ :  Union[str, Any]							      =					{"""input_ids""": batch[0], """attention_mask""": batch[1], """labels""": batch[3]}

      if self.config.model_type not in ["distilbert", "bart"]:
          lowerCAmelCase__ :  Optional[int]							      =					batch[2] if self.config.model_type in ["""bert""", """xlnet""", """albert"""] else None

      lowerCAmelCase__ :  Dict							      =					self(**__UpperCAmelCase      )
      lowerCAmelCase__      ,   lowerCAmelCase__ :  Optional[Any]							      =					outputs[:2]
      lowerCAmelCase__ :  Dict							      =					logits.detach().cpu().numpy()
      lowerCAmelCase__ :  Any							      =					inputs["""labels"""].detach().cpu().numpy()

      return {"val_loss": tmp_eval_loss.detach().cpu(), "pred": preds, "target": out_label_ids}




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase      )    ->		tuple:
      lowerCAmelCase__ :  Union[str, Any]							      =					torch.stack([x["""val_loss"""] for x in outputs]      ).mean().detach().cpu().item()
      lowerCAmelCase__ :  Dict							      =					np.concatenate([x["""pred"""] for x in outputs]  ,axis=0      )

      if self.hparams.glue_output_mode == "classification":
          lowerCAmelCase__ :  Union[str, Any]							      =					np.argmax(__UpperCAmelCase  ,axis=1      )
      elif self.hparams.glue_output_mode == "regression":
          lowerCAmelCase__ :  Tuple							      =					np.squeeze(__UpperCAmelCase      )

      lowerCAmelCase__ :  List[Any]							      =					np.concatenate([x["""target"""] for x in outputs]  ,axis=0      )
      lowerCAmelCase__ :  Dict							      =					[[] for _ in range(out_label_ids.shape[0]      )]
      lowerCAmelCase__ :  List[Any]							      =					[[] for _ in range(out_label_ids.shape[0]      )]

      lowerCAmelCase__ :  List[Any]							      =					{**{"""val_loss""": val_loss_mean}, **compute_metrics(self.hparams.task  ,__UpperCAmelCase  ,__UpperCAmelCase      )}

      lowerCAmelCase__ :  Dict							      =					dict(results.items()      )
      lowerCAmelCase__ :  Optional[Any]							      =					results
      return ret, preds_list, out_label_list




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase      )    ->		dict:
      lowerCAmelCase__      ,   lowerCAmelCase__      ,   lowerCAmelCase__ :  Union[str, Any]							      =					self._eval_end(__UpperCAmelCase      )
      lowerCAmelCase__ :  int							      =					ret["""log"""]
      return {"val_loss": logs["val_loss"], "log": logs, "progress_bar": logs}




  def 							UpperCAmelCase_	(    self  ,__UpperCAmelCase      )    ->		dict:
      lowerCAmelCase__      ,   lowerCAmelCase__      ,   lowerCAmelCase__ :  List[Any]							      =					self._eval_end(__UpperCAmelCase      )
      lowerCAmelCase__ :  str							      =					ret["""log"""]
      # `val_loss` is the key returned by `self._eval_end()` but actually refers to `test_loss`
      return {"avg_test_loss": logs["val_loss"], "log": logs, "progress_bar": logs}






  @staticmethod
  def 							UpperCAmelCase_	(    __UpperCAmelCase  ,__UpperCAmelCase      )    ->		int:
      BaseTransformer.add_model_specific_args(__UpperCAmelCase  ,__UpperCAmelCase      )
      parser.add_argument(
          """--max_seq_length"""  ,default=128  ,type=__UpperCAmelCase  ,help=(
              """The maximum total input sequence length after tokenization. Sequences longer """
              """than this will be truncated, sequences shorter will be padded."""
          )  ,)

      parser.add_argument(
          """--task"""  ,default=""""""  ,type=__UpperCAmelCase  ,required=__UpperCAmelCase  ,help="""The GLUE task to run"""  ,)
      parser.add_argument(
          """--gpus"""  ,default=0  ,type=__UpperCAmelCase  ,help="""The number of GPUs allocated for this, it is by default 0 meaning none"""  ,)

      parser.add_argument(
          """--overwrite_cache"""  ,action="""store_true"""  ,help="""Overwrite the cached training and evaluation sets"""      )

      return parser







def    _SCREAMING_SNAKE_CASE  (       ):



    """simple docstring"""





    lowerCAmelCase__ :  Any							      =					argparse.ArgumentParser()
    add_generic_args(UpperCamelCase							,    os.getcwd()			)
    lowerCAmelCase__ :  Optional[int]							      =					GLUETransformer.add_model_specific_args(UpperCamelCase							,    os.getcwd()			)
    lowerCAmelCase__ :  Optional[Any]							      =					parser.parse_args()

    # If output_dir not provided, a folder will be generated in pwd
    if args.output_dir is None:
        lowerCAmelCase__ :  Union[str, Any]							      =					os.path.join(
            """./results"""							,    f"""{args.task}_{time.strftime('%Y%m%d_%H%M%S'			)}"""							,    )
        os.makedirs(args.output_dir			)

    lowerCAmelCase__ :  str							      =					GLUETransformer(UpperCamelCase			)
    lowerCAmelCase__ :  Optional[Any]							      =					generic_train(UpperCamelCase							,    UpperCamelCase			)

    # Optionally, predict on dev set and write to output_dir
    if args.do_predict:
        lowerCAmelCase__ :  str							      =					sorted(glob.glob(os.path.join(args.output_dir							,    """checkpoint-epoch=*.ckpt"""			)							,    recursive=UpperCamelCase			)			)
        lowerCAmelCase__ :  List[Any]							      =					model.load_from_checkpoint(checkpoints[-1]			)
        return trainer.test(UpperCamelCase			)


if __name__ == "__main__":
 main()







'''simple docstring'''





def    _SCREAMING_SNAKE_CASE  (       UpperCamelCase			):



    """simple docstring"""





    lowerCAmelCase__ :  Tuple							      =					abs(UpperCamelCase			)
    lowerCAmelCase__ :  List[Any]							      =					0
    while n > 0:
        res += n % 10
        n //= 10
    return res
def    _SCREAMING_SNAKE_CASE  (       UpperCamelCase			):



    """simple docstring"""





    lowerCAmelCase__ :  Union[str, Any]							      =					abs(UpperCamelCase			)
    return n if n < 10 else n % 10 + sum_of_digits(n // 10			)
def    _SCREAMING_SNAKE_CASE  (       UpperCamelCase			):



    """simple docstring"""





    return sum(int(UpperCamelCase			) for c in str(abs(UpperCamelCase			)			)			)
def    _SCREAMING_SNAKE_CASE  (       ):



    """simple docstring"""





    from collections.abc import Callable
    from timeit import timeit

    def benchmark_a_function(UpperCamelCase							,    UpperCamelCase			) -> None:
        lowerCAmelCase__ :  str							      =					f"""{func.__name__}({value})"""
        lowerCAmelCase__ :  str							      =					timeit(f"""__main__.{call}"""							,    setup="""import __main__"""			)
        print(f"""{call:56} = {func(UpperCamelCase			)} -- {timing:.4f} seconds"""			)

    for value in (262144, 1125899906842624, 1267650600228229401496703205376):
        for func in (sum_of_digits, sum_of_digits_recursion, sum_of_digits_compact):
            benchmark_a_function(UpperCamelCase							,    UpperCamelCase			)
        print()


if __name__ == "__main__":
 import doctest

 doctest.testmod()
 benchmark()


