


"""simple docstring"""





import argparse
import logging
import os
from pathlib import Path
from typing import Any, Dict

import pytorch_lightning as pl
from pytorch_lightning.utilities import rank_zero_info

from transformers import (
    AdamW,
    AutoConfig,
    AutoModel,
    AutoModelForPreTraining,
    AutoModelForQuestionAnswering,
    AutoModelForSeqaSeqLM,
    AutoModelForSequenceClassification,
    AutoModelForTokenClassification,
    AutoModelWithLMHead,
    AutoTokenizer,
    PretrainedConfig,
    PreTrainedTokenizer,
)
from transformers.optimization import (
    Adafactor,
    get_cosine_schedule_with_warmup,
    get_cosine_with_hard_restarts_schedule_with_warmup,
    get_linear_schedule_with_warmup,
    get_polynomial_decay_schedule_with_warmup,
)
from transformers.utils.versions import require_version


__UpperCAmelCase    				=      logging.getLogger(__name__)

require_version("pytorch_lightning>=1.0.4")

__UpperCAmelCase    				=      {
    "base": AutoModel,
    "sequence-classification": AutoModelForSequenceClassification,
    "question-answering": AutoModelForQuestionAnswering,
    "pretraining": AutoModelForPreTraining,
    "token-classification": AutoModelForTokenClassification,
    "language-modeling": AutoModelWithLMHead,
    "summarization": AutoModelForSeqaSeqLM,
    "translation": AutoModelForSeqaSeqLM,
}


# update this and the import above to support new schedulers from transformers.optimization
__UpperCAmelCase    				=      {
    "linear": get_linear_schedule_with_warmup,
    "cosine": get_cosine_schedule_with_warmup,
    "cosine_w_restarts": get_cosine_with_hard_restarts_schedule_with_warmup,
    "polynomial": get_polynomial_decay_schedule_with_warmup,
    # '': get_constant_schedule,             # not supported for now
    # '': get_constant_schedule_with_warmup, # not supported for now
}
__UpperCAmelCase    				=      sorted(arg_to_scheduler.keys())
__UpperCAmelCase    				=      "{" + ", ".join(arg_to_scheduler_choices) + "}"

class  lowercase_  ( pl.LightningModule						):







      def __init__(      self :							Dict		,  _lowercase :							argparse.Namespace		,  _lowercase :							int=None		,  _lowercase :							Tuple="base"		,  _lowercase :							str=None		,  _lowercase :							str=None		,  _lowercase :							List[Any]=None		,  **_lowercase :							Tuple		,  ):
        super().__init__()
        # TODO: move to self.save_hyperparameters()
        # self.save_hyperparameters()
        # can also expand arguments into trainer signature for easier reading

        self.save_hyperparameters(_lowercase    )
        lowerCAmelCase__    :    List[str]								=					0
        lowerCAmelCase__    :    Optional[Any]								=					Path(self.hparams.output_dir    )
        lowerCAmelCase__    :    Tuple								=					self.hparams.cache_dir if self.hparams.cache_dir else None
        if config is None:
          lowerCAmelCase__    :    Dict								=					AutoConfig.from_pretrained(
              self.hparams.config_name if self.hparams.config_name else self.hparams.model_name_or_path		,  **({"num_labels": num_labels} if num_labels is not None else {})		,  cache_dir=_lowercase		,  **_lowercase		,  )
        else:
          lowerCAmelCase__    :    PretrainedConfig								=					config

        lowerCAmelCase__    :    Optional[int]								=					("encoder_layerdrop", "decoder_layerdrop", "dropout", "attention_dropout")
        for p in extra_model_params:
          if getattr(self.hparams		,  _lowercase		,  _lowercase    ):
            assert hasattr(self.config		,  _lowercase    ), f"model config doesn't have a `{p}` attribute"
            setattr(self.config		,  _lowercase		,  getattr(self.hparams		,  _lowercase    )    )

        if tokenizer is None:
          lowerCAmelCase__    :    Any								=					AutoTokenizer.from_pretrained(
              self.hparams.tokenizer_name if self.hparams.tokenizer_name else self.hparams.model_name_or_path		,  cache_dir=_lowercase		,  )
        else:
          lowerCAmelCase__    :    PreTrainedTokenizer								=					tokenizer
        lowerCAmelCase__    :    List[str]								=					MODEL_MODES[mode]
        if model is None:
          lowerCAmelCase__    :    List[Any]								=					self.model_type.from_pretrained(
              self.hparams.model_name_or_path		,  from_tf=bool(".ckpt" in self.hparams.model_name_or_path    )		,  config=self.config		,  cache_dir=_lowercase		,  )
        else:
          lowerCAmelCase__    :    List[str]								=					model







      def 				_lowerCAmelCase       (      self :							Optional[int]		,  *_lowercase :							Any		,  **_lowercase :							int    ):
        lowerCAmelCase__    :    str								=					self.model_type.from_pretrained(*_lowercase		,  **_lowercase    )







      def 				_lowerCAmelCase       (      self :							Optional[int]    ):
        lowerCAmelCase__    :    int								=					arg_to_scheduler[self.hparams.lr_scheduler]
        lowerCAmelCase__    :    List[str]								=					get_schedule_func(
            self.opt		,  num_warmup_steps=self.hparams.warmup_steps		,  num_training_steps=self.total_steps()    )
        lowerCAmelCase__    :    int								=					{"scheduler": scheduler, "interval": "step", "frequency": 1}
        return scheduler







      def 				_lowerCAmelCase       (      self :							int    ):
        lowerCAmelCase__    :    Union[str, Any]								=					self.model
        lowerCAmelCase__    :    Union[str, Any]								=					["bias", "LayerNorm.weight"]
        lowerCAmelCase__    :    str								=					[
            {
                "params": [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay    )],
                "weight_decay": self.hparams.weight_decay,
            },
            {
                "params": [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay    )],
                "weight_decay": 0.0,
            },
        ]
        if self.hparams.adafactor:
          lowerCAmelCase__    :    int								=					Adafactor(
              _lowercase		,  lr=self.hparams.learning_rate		,  scale_parameter=_lowercase		,  relative_step=_lowercase    )

        else:
          lowerCAmelCase__    :    List[Any]								=					AdamW(
              _lowercase		,  lr=self.hparams.learning_rate		,  eps=self.hparams.adam_epsilon    )
        lowerCAmelCase__    :    Dict								=					optimizer

        lowerCAmelCase__    :    List[Any]								=					self.get_lr_scheduler()

        return [optimizer], [scheduler]







      def 				_lowerCAmelCase       (      self :							Optional[int]		,  _lowercase :							Dict		,  _lowercase :							List[str]    ):
        return self.validation_step(_lowercase		,  _lowercase    )







      def 				_lowerCAmelCase       (      self :							int		,  _lowercase :							List[Any]    ):
        return self.validation_end(_lowercase    )







      def 				_lowerCAmelCase       (      self :							int    ):
        lowerCAmelCase__    :    Optional[Any]								=					max(1		,  self.hparams.gpus    )  # TODO: consider num_tpu_cores
        lowerCAmelCase__    :    Any								=					self.hparams.train_batch_size * self.hparams.accumulate_grad_batches * num_devices
        return (self.dataset_size / effective_batch_size) * self.hparams.max_epochs







      def 				_lowerCAmelCase       (      self :							List[Any]		,  _lowercase :							Optional[int]    ):
        if mode == "test":
          lowerCAmelCase__    :    str								=					len(self.test_dataloader().dataset    )
        else:
          lowerCAmelCase__    :    Optional[int]								=					self.get_dataloader("train"		,  self.hparams.train_batch_size		,  shuffle=_lowercase    )
          lowerCAmelCase__    :    Dict								=					len(self.train_dataloader().dataset    )







      def 				_lowerCAmelCase       (      self :							Dict		,  _lowercase :							str		,  _lowercase :							int		,  _lowercase :							bool = False    ):
        raise NotImplementedError("You must implement this for your task"    )







      def 				_lowerCAmelCase       (      self :							Tuple    ):
        return self.train_loader







      def 				_lowerCAmelCase       (      self :							str    ):
        return self.get_dataloader("dev"		,  self.hparams.eval_batch_size		,  shuffle=_lowercase    )







      def 				_lowerCAmelCase       (      self :							Optional[Any]    ):
        return self.get_dataloader("test"		,  self.hparams.eval_batch_size		,  shuffle=_lowercase    )







      def 				_lowerCAmelCase       (      self :							Any		,  _lowercase :							int    ):
        return os.path.join(
            self.hparams.data_dir		,  "cached_{}_{}_{}".format(
                _lowercase		,  list(filter(_lowercase		,  self.hparams.model_name_or_path.split("/"    )    )    ).pop()		,  str(self.hparams.max_seq_length    )		,  )		,  )







      @pl.utilities.rank_zero_only
      def 				_lowerCAmelCase       (      self :							int		,  _lowercase :							Dict[str, Any]    ):
        lowerCAmelCase__    :    Any								=					self.output_dir.joinpath("best_tfmr"    )
        lowerCAmelCase__    :    Tuple								=					self.step_count
        self.model.save_pretrained(_lowercase    )
        self.tokenizer.save_pretrained(_lowercase    )







      @staticmethod
      def 				_lowerCAmelCase       (      _lowercase :							str		,  _lowercase :							Optional[int]    ):
        parser.add_argument(
            "--model_name_or_path"		,  default=_lowercase		,  type=_lowercase		,  required=_lowercase		,  help="Path to pretrained model or model identifier from huggingface.co/models"		,  )
        parser.add_argument(
            "--config_name"		,  default=""		,  type=_lowercase		,  help="Pretrained config name or path if not the same as model_name"    )
        parser.add_argument(
            "--tokenizer_name"		,  default=_lowercase		,  type=_lowercase		,  help="Pretrained tokenizer name or path if not the same as model_name"		,  )
        parser.add_argument(
            "--cache_dir"		,  default=""		,  type=_lowercase		,  help="Where do you want to store the pre-trained models downloaded from huggingface.co"		,  )
        parser.add_argument(
            "--encoder_layerdrop"		,  type=_lowercase		,  help="Encoder layer dropout probability (Optional). Goes into model.config"		,  )
        parser.add_argument(
            "--decoder_layerdrop"		,  type=_lowercase		,  help="Decoder layer dropout probability (Optional). Goes into model.config"		,  )
        parser.add_argument(
            "--dropout"		,  type=_lowercase		,  help="Dropout probability (Optional). Goes into model.config"		,  )
        parser.add_argument(
            "--attention_dropout"		,  type=_lowercase		,  help="Attention dropout probability (Optional). Goes into model.config"		,  )
        parser.add_argument("--learning_rate"		,  default=5e-5		,  type=_lowercase		,  help="The initial learning rate for Adam."    )
        parser.add_argument(
            "--lr_scheduler"		,  default="linear"		,  choices=_lowercase		,  metavar=_lowercase		,  type=_lowercase		,  help="Learning rate scheduler"		,  )
        parser.add_argument("--weight_decay"		,  default=0.0		,  type=_lowercase		,  help="Weight decay if we apply some."    )
        parser.add_argument("--adam_epsilon"		,  default=1e-8		,  type=_lowercase		,  help="Epsilon for Adam optimizer."    )
        parser.add_argument("--warmup_steps"		,  default=0		,  type=_lowercase		,  help="Linear warmup over warmup_steps."    )
        parser.add_argument("--num_workers"		,  default=4		,  type=_lowercase		,  help="kwarg passed to DataLoader"    )
        parser.add_argument("--num_train_epochs"		,  dest="max_epochs"		,  default=3		,  type=_lowercase    )
        parser.add_argument("--train_batch_size"		,  default=3_2		,  type=_lowercase    )
        parser.add_argument("--eval_batch_size"		,  default=3_2		,  type=_lowercase    )
        parser.add_argument("--adafactor"		,  action="store_true"    )

class  lowercase_  ( pl.Callback						):







      def 				_lowerCAmelCase       (      self :							Optional[Any]		,  _lowercase :							Optional[int]		,  _lowercase :							Optional[int]    ):
        lowerCAmelCase__    :    Union[str, Any]								=					trainer.lr_schedulers[0]["scheduler"]
        lowerCAmelCase__    :    Union[str, Any]								=					{f"lr_group_{i}": lr for i, lr in enumerate(lr_scheduler.get_lr()    )}
        pl_module.logger.log_metrics(_lowercase    )







      def 				_lowerCAmelCase       (      self :							Tuple		,  _lowercase :							pl.Trainer		,  _lowercase :							pl.LightningModule    ):
        rank_zero_info("***** Validation results *****"    )
        lowerCAmelCase__    :    List[str]								=					trainer.callback_metrics
        # Log results
        for key in sorted(_lowercase    ):
          if key not in ["log", "progress_bar"]:
            rank_zero_info("{} = {}\n".format(_lowercase		,  str(metrics[key]    )    )    )







      def 				_lowerCAmelCase       (      self :							Optional[int]		,  _lowercase :							pl.Trainer		,  _lowercase :							pl.LightningModule    ):
        rank_zero_info("***** Test results *****"    )
        lowerCAmelCase__    :    Optional[Any]								=					trainer.callback_metrics
        # Log and save results to file
        lowerCAmelCase__    :    Optional[Any]								=					os.path.join(pl_module.hparams.output_dir		,  "test_results.txt"    )
        with open(_lowercase		,  "w"    ) as writer:
          for key in sorted(_lowercase    ):
            if key not in ["log", "progress_bar"]:
              rank_zero_info("{} = {}\n".format(_lowercase		,  str(metrics[key]    )    )    )
              writer.write("{} = {}\n".format(_lowercase		,  str(metrics[key]    )    )    )





def     lowercase__	(  lowerCamelCase     :  Dict				,	lowerCamelCase     :  Tuple				)					->     None:
  #  To allow all pl args uncomment the following line
  #  parser = pl.Trainer.add_argparse_args(parser)
  parser.add_argument(
      "--output_dir"				,	default=lowerCamelCase				,	type=lowerCamelCase				,	required=lowerCamelCase				,	help="The output directory where the model predictions and checkpoints will be written."				,	)
  parser.add_argument(
      "--fp16"				,	action="store_true"				,	help="Whether to use 16-bit (mixed) precision (through NVIDIA apex) instead of 32-bit"				,	)

  parser.add_argument(
      "--fp16_opt_level"				,	type=lowerCamelCase				,	default="O2"				,	help=(
          "For fp16: Apex AMP optimization level selected in ['O0', 'O1', 'O2', and 'O3']."
          "See details at https://nvidia.github.io/apex/amp.html"
      )				,	)
  parser.add_argument("--n_tpu_cores"				,	dest="tpu_cores"				,	type=lowerCamelCase				)
  parser.add_argument("--max_grad_norm"				,	dest="gradient_clip_val"				,	default=1.0				,	type=lowerCamelCase				,	help="Max gradient norm"				)
  parser.add_argument("--do_train"				,	action="store_true"				,	help="Whether to run training."				)
  parser.add_argument("--do_predict"				,	action="store_true"				,	help="Whether to run predictions on the test set."				)
  parser.add_argument(
      "--gradient_accumulation_steps"				,	dest="accumulate_grad_batches"				,	type=lowerCamelCase				,	default=1				,	help="Number of updates steps to accumulate before performing a backward/update pass."				,	)
  parser.add_argument("--seed"				,	type=lowerCamelCase				,	default=4_2				,	help="random seed for initialization"				)
  parser.add_argument(
      "--data_dir"				,	default=lowerCamelCase				,	type=lowerCamelCase				,	required=lowerCamelCase				,	help="The input data dir. Should contain the training files for the CoNLL-2003 NER task."				,	)







def     lowercase__	(  lowerCamelCase     :  BaseTransformer				,	lowerCamelCase     :  argparse.Namespace				,	lowerCamelCase     :  Dict=None				,	lowerCamelCase     :  List[Any]=True				,	lowerCamelCase     :  Union[str, Any]=[]				,	lowerCamelCase     :  List[Any]=None				,	lowerCamelCase     :  List[str]=None				,	**lowerCamelCase     :  str				,	)					->     Optional[int]:
  pl.seed_everything(args.seed				)

  # init model
  lowerCAmelCase__    :    Tuple								=					Path(model.hparams.output_dir				)
  odir.mkdir(exist_ok=lowerCamelCase				)

  # add custom checkpoints
  if checkpoint_callback is None:
    lowerCAmelCase__    :    Optional[int]								=					pl.callbacks.ModelCheckpoint(
        filepath=args.output_dir				,	prefix="checkpoint"				,	monitor="val_loss"				,	mode="min"				,	save_top_k=1				)
  if early_stopping_callback:
    extra_callbacks.append(lowerCamelCase				)
  if logging_callback is None:
    lowerCAmelCase__    :    Tuple								=					LoggingCallback()

  lowerCAmelCase__    :    Union[str, Any]								=					{}

  # TODO: remove with PyTorch 1.6 since pl uses native amp
  if args.fpaa:
    lowerCAmelCase__    :    Tuple								=					1_6
    lowerCAmelCase__    :    List[Any]								=					args.fpaa_opt_level

  if args.gpus > 1:
    lowerCAmelCase__    :    Dict								=					"ddp"

  lowerCAmelCase__    :    List[Any]								=					args.accumulate_grad_batches
  lowerCAmelCase__    :    Any								=					extra_train_kwargs.get("accelerator"				,	lowerCamelCase				)
  lowerCAmelCase__    :    Tuple								=					extra_train_kwargs.get("profiler"				,	lowerCamelCase				)

  lowerCAmelCase__    :    int								=					pl.Trainer.from_argparse_args(
      lowerCamelCase				,	weights_summary=lowerCamelCase				,	callbacks=[logging_callback] + extra_callbacks				,	logger=lowerCamelCase				,	checkpoint_callback=lowerCamelCase				,	**lowerCamelCase				,	)

  if args.do_train:
    trainer.fit(lowerCamelCase				)

  return trainer




"""simple docstring"""





def     lowercase__	(  lowerCamelCase     :  int				)					->     int:
  if not isinstance(lowerCamelCase				,	lowerCamelCase				):
    raise TypeError("recursive_lucas_number accepts only integer arguments."				)
  if n_th_number == 0:
    return 2
  if n_th_number == 1:
    return 1

  return recursive_lucas_number(n_th_number - 1				) + recursive_lucas_number(
      n_th_number - 2				)





def     lowercase__	(  lowerCamelCase     :  int				)					->     int:
  if not isinstance(lowerCamelCase				,	lowerCamelCase				):
    raise TypeError("dynamic_lucas_number accepts only integer arguments."				)
  lowerCAmelCase__				,		lowerCAmelCase__    :    str								=					2, 1
  for _ in range(lowerCamelCase				):
    lowerCAmelCase__				,		lowerCAmelCase__    :    str								=					b, a + b
  return a


if __name__ == "__main__":
   from doctest import testmod

   testmod()
   __UpperCAmelCase    				=      int(input("Enter the number of terms in lucas series:\n").strip())
   print("Using recursive function to calculate lucas series:")
   print(" ".join(str(recursive_lucas_number(i)) for i in range(n)))
   print("\nUsing dynamic function to calculate lucas series:")
   print(" ".join(str(dynamic_lucas_number(i)) for i in range(n)))
