






'''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 							_UpperCAmelCase    (		pl.LightningModule      ):




    def __init__(      self	:							str	,  a	:							Union[str, Any]	,  a	:							str=None	,  a	:							str="base"	,  a	:							Any=None	,  a	:							Union[str, Any]=None	,  a	:							Union[str, Any]=None	,  **a	:							List[str]	,  ):






       '''simple docstring'''






       super().__init__()
       # TODO: move to self.save_hyperparameters()
       # self.save_hyperparameters()
       # can also expand arguments into trainer signature for easier reading

       self.save_hyperparameters(snake_case_      )
       lowercase_						:     Tuple							     =  0
       lowercase_						:     Tuple							     =  Path(self.hparams.output_dir      )
       lowercase_						:     Any							     =  self.hparams.cache_dir if self.hparams.cache_dir else None
       if config is None:
          lowercase_						:     Union[str, Any]							     =  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=snake_case_	,  **snake_case_	,  )
       else:
          lowercase_						:     PretrainedConfig							     =  config

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

       if tokenizer is None:
          lowercase_						:     str							     =  AutoTokenizer.from_pretrained(
              self.hparams.tokenizer_name if self.hparams.tokenizer_name else self.hparams.model_name_or_path	,  cache_dir=snake_case_	,  )
       else:
          lowercase_						:     PreTrainedTokenizer							     =  tokenizer
       lowercase_						:     str							     =  MODEL_MODES[mode]
       if model is None:
          lowercase_						:     List[str]							     =  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=snake_case_	,  )
       else:
          lowercase_						:     Optional[int]							     =  model




    def 					lowerCAmelCase__					(      self	:							List[str]	,  *a	:							Dict	,  **a	:							Optional[Any]      ):






       '''simple docstring'''






       lowercase_						:     Optional[Any]							     =  self.model_type.from_pretrained(*snake_case_	,  **snake_case_      )




    def 					lowerCAmelCase__					(      self	:							List[str]      ):






       '''simple docstring'''






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




    def 					lowerCAmelCase__					(      self	:							int      ):






       '''simple docstring'''






       lowercase_						:     List[str]							     =  self.model
       lowercase_						:     Optional[Any]							     =  ["""bias""", """LayerNorm.weight"""]
       lowercase_						:     List[str]							     =  [
           {
               """params""": [
                   p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay      )
               ],  # check this named paramters
               """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:
          lowercase_						:     Optional[Any]							     =  Adafactor(
              snake_case_	,  lr=self.hparams.learning_rate	,  scale_parameter=snake_case_	,  relative_step=snake_case_      )

       else:
          lowercase_						:     str							     =  AdamW(
              snake_case_	,  lr=self.hparams.learning_rate	,  eps=self.hparams.adam_epsilon      )
       lowercase_						:     str							     =  optimizer

       lowercase_						:     Dict							     =  self.get_lr_scheduler()

       return [optimizer], [scheduler]




    def 					lowerCAmelCase__					(      self	:							Dict	,  a	:							List[Any]	,  a	:							Optional[Any]      ):






       '''simple docstring'''






       return self.validation_step(snake_case_	,  snake_case_      )




    def 					lowerCAmelCase__					(      self	:							Union[str, Any]	,  a	:							Any      ):






       '''simple docstring'''






       return self.validation_end(snake_case_      )




    def 					lowerCAmelCase__					(      self	:							Union[str, Any]      ):






       '''simple docstring'''






       lowercase_						:     Optional[int]							     =  max(1	,  self.hparams.gpus      )  # TODO: consider num_tpu_cores
       lowercase_						:     Optional[int]							     =  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]	,  a	:							Optional[Any]      ):






       '''simple docstring'''






       if stage == "test":
          lowercase_						:     Optional[Any]							     =  len(self.test_dataloader().dataset      )
       else:
          lowercase_						:     int							     =  self.get_dataloader("train"	,  self.hparams.train_batch_size	,  shuffle=snake_case_      )
          lowercase_						:     int							     =  len(self.train_dataloader().dataset      )




    def 					lowerCAmelCase__					(      self	:							Tuple	,  a	:							Union[str, Any]	,  a	:							List[str]	,  a	:							Dict = False      ):






       '''simple docstring'''






       raise NotImplementedError("You must implement this for your task"      )




    def 					lowerCAmelCase__					(      self	:							Optional[int]      ):






       '''simple docstring'''






       return self.train_loader




    def 					lowerCAmelCase__					(      self	:							Optional[Any]      ):






       '''simple docstring'''






       return self.get_dataloader("dev"	,  self.hparams.eval_batch_size	,  shuffle=snake_case_      )




    def 					lowerCAmelCase__					(      self	:							List[Any]      ):






       '''simple docstring'''






       return self.get_dataloader("test"	,  self.hparams.eval_batch_size	,  shuffle=snake_case_      )




    def 					lowerCAmelCase__					(      self	:							List[Any]	,  a	:							Union[str, Any]      ):






       '''simple docstring'''






       return os.path.join(
           self.hparams.data_dir	,  "cached_{}_{}_{}".format(
               snake_case_	,  list(filter(snake_case_	,  self.hparams.model_name_or_path.split("/"      )      )      ).pop()	,  str(self.hparams.max_seq_length      )	,  )	,  )




    @pl.utilities.rank_zero_only
    def 					lowerCAmelCase__					(      self	:							Union[str, Any]	,  a	:							Tuple      ):






       '''simple docstring'''






       lowercase_						:     Any							     =  self.output_dir.joinpath("best_tfmr"      )
       lowercase_						:     Any							     =  self.step_count
       self.model.save_pretrained(snake_case_      )
       self.tokenizer.save_pretrained(snake_case_      )





    @staticmethod
    def 					lowerCAmelCase__					(      a	:							str	,  a	:							Any      ):






       '''simple docstring'''






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


class 							_UpperCAmelCase    (		pl.Callback      ):




    def 					lowerCAmelCase__					(      self	:							int	,  a	:							List[Any]	,  a	:							Optional[Any]      ):






       '''simple docstring'''






       if (
           trainer.is_global_zero and trainer.global_rank == 0
       ):  # we initialize the retriever only on master worker with RAY. In new pytorch-lightning accelorators are removed.
          pl_module.model.rag.retriever.init_retrieval()  # better to use hook functions.


class 							_UpperCAmelCase    (		pl.Callback      ):




    def 					lowerCAmelCase__					(      self	:							Optional[Any]	,  a	:							Tuple	,  a	:							List[Any]      ):






       '''simple docstring'''






       for name, param in pl_module.model.rag.named_parameters():
          if param.grad is None:
             print(snake_case_      )


class 							_UpperCAmelCase    (		pl.Callback      ):




    def 					lowerCAmelCase__					(      self	:							List[Any]	,  a	:							Dict	,  a	:							Any      ):






       '''simple docstring'''






       lowercase_						:     List[str]							     =  trainer.lr_schedulers[0]["""scheduler"""]
       lowercase_						:     Any							     =  {f"""lr_group_{i}""": lr for i, lr in enumerate(lr_scheduler.get_lr()      )}
       pl_module.logger.log_metrics(snake_case_      )




    def 					lowerCAmelCase__					(      self	:							List[str]	,  a	:							List[str]	,  a	:							Any      ):






       '''simple docstring'''






       rank_zero_info("***** Validation results *****"      )
       lowercase_						:     Optional[int]							     =  trainer.callback_metrics
       # Log results
       for key in sorted(snake_case_      ):
          if key not in ["log", "progress_bar"]:
             rank_zero_info("{} = {}\n".format(snake_case_	,  str(metrics[key]      )      )      )





    def 					lowerCAmelCase__					(      self	:							List[str]	,  a	:							List[str]	,  a	:							str      ):






       '''simple docstring'''






       rank_zero_info("***** Test results *****"      )
       lowercase_						:     List[str]							     =  trainer.callback_metrics
       # Log and save results to file
       lowercase_						:     List[Any]							     =  os.path.join(pl_module.hparams.output_dir	,  "test_results.txt"      )
       with open(snake_case_	,  "w"      ) as writer:
          for key in sorted(snake_case_      ):
             if key not in ["log", "progress_bar"]:
                rank_zero_info("{} = {}\n".format(snake_case_	,  str(metrics[key]      )      )      )
                writer.write("{} = {}\n".format(snake_case_	,  str(metrics[key]      )      )      )




def 		__SCREAMING_SNAKE_CASE       (	_UpperCamelCase    ,		_UpperCamelCase				):


   """simple docstring"""




   parser.add_argument(
       "--output_dir"    ,		default=str(Path(_UpperCamelCase				).parent / "test_run" / "model_checkpoints"				)    ,		type=_UpperCamelCase    ,		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=_UpperCamelCase    ,		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=_UpperCamelCase				)
   parser.add_argument("--max_grad_norm"    ,		dest="gradient_clip_val"    ,		default=1.0    ,		type=_UpperCamelCase    ,		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=_UpperCamelCase    ,		default=1    ,		help="Number of updates steps to accumulate before performing a backward/update pass."    ,		)
   parser.add_argument("--seed"    ,		type=_UpperCamelCase    ,		default=42    ,		help="random seed for initialization"				)
   parser.add_argument(
       "--data_dir"    ,		default=str(Path(_UpperCamelCase				).parent / "test_run" / "dummy-train-data"				)    ,		type=_UpperCamelCase    ,		help="The input data dir. Should contain the training files for the CoNLL-2003 NER task."    ,		)





def 		__SCREAMING_SNAKE_CASE       (	_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase=None    ,		_UpperCamelCase=True    ,		_UpperCamelCase=[]    ,		_UpperCamelCase=None    ,		_UpperCamelCase=None    ,		**_UpperCamelCase    ,		):


   """simple docstring"""




   pl.seed_everything(args.seed				)

   # init model
   lowercase_						:     Union[str, Any]							     =  Path(model.hparams.output_dir				)
   odir.mkdir(exist_ok=_UpperCamelCase				)

   # add custom checkpoints
   if checkpoint_callback is None:
      lowercase_						:     List[Any]							     =  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(_UpperCamelCase				)
   if logging_callback is None:
      lowercase_						:     str							     =  LoggingCallback()

   lowercase_						:     Optional[Any]							     =  {}

   if args.fpaa:
      lowercase_						:     List[str]							     =  16

   if args.gpus > 1:
      lowercase_						:     Optional[int]							     =  """auto"""
      lowercase_						:     Tuple							     =  """ddp"""

   lowercase_						:     int							     =  args.accumulate_grad_batches
   lowercase_						:     Union[str, Any]							     =  None
   lowercase_						:     Any							     =  """auto"""

   lowercase_						:     List[str]							     =  pl.Trainer.from_argparse_args(
       _UpperCamelCase    ,		weights_summary=_UpperCamelCase    ,		callbacks=[logging_callback] + extra_callbacks + [InitCallback()] + [checkpoint_callback]    ,		logger=_UpperCamelCase    ,		val_check_interval=1    ,		num_sanity_val_steps=2    ,		**_UpperCamelCase    ,		)

   if args.do_train:
      trainer.fit(_UpperCamelCase				)

   else:
      print("RAG modeling tests with new set functions successfuly executed!"				)
   return trainer





"""simple docstring"""



from collections import defaultdict
class 						__UpperCAmelCase    :







			'''simple docstring'''





			def __init__(			self   ,      snake_case_   ,      snake_case_							):







										'''simple docstring'''


										A__       :     Tuple								=			total  # total no of tasks (N)

										# DP table will have a dimension of (2^M)*N
										# initially all values are set to -1
										A__       :     Optional[int]								=			[
										    [-1 for i in range(total + 1							)] for j in range(2 ** len(snake_case_							)							)
										]

										A__       :     Optional[int]								=			defaultdict(snake_case_							)  # stores the list of persons for each task

										# final_mask is used to check if all persons are included by setting all bits
										# to 1
										A__       :     Optional[int]								=			(1 << len(snake_case_							)) - 1





			def 		lowerCamelCase					(			self   ,      snake_case_   ,      snake_case_							):







										'''simple docstring'''


										if mask == self.final_mask:
																	return 1

										# if not everyone gets the task and no more tasks are available, return 0
										if task_no > self.total_tasks:
																	return 0

										# if case already considered
										if self.dp[mask][task_no] != -1:
																	return self.dp[mask][task_no]

										# Number of ways when we don't this task in the arrangement
										A__       :     Optional[int]								=			self.count_ways_until(snake_case_   ,      task_no + 1							)

										# now assign the tasks one by one to all possible persons and recursively
										# assign for the remaining tasks.
										if task_no in self.task:
																	for p in self.task[task_no]:
																								# if p is already given a task
																								if mask & (1 << p):
																															continue

																								# assign this task to p and change the mask value. And recursively
																								# assign tasks with the new mask value.
																								total_ways_util += self.count_ways_until(mask | (1 << p)   ,      task_no + 1							)

        # save the value.
										A__       :     List[str]								=			total_ways_util

										return self.dp[mask][task_no]





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


										for i in range(len(snake_case_							)							):
																	for j in task_performed[i]:
																								self.task[j].append(snake_case_							)

        # call the function to fill the DP table, final answer is stored in dp[0][1]
										return self.count_ways_until(0   ,      1							)


if __name__ == "__main__":
				_UpperCamelCase								=		5  # total no of tasks (the value of N)

				# the list of tasks that can be done by M persons.
				_UpperCamelCase								=		[[1, 3, 4], [1, 2, 5], [3, 4]]
				print(
				    AssignmentUsingBitmask(task_performed, total_tasks).count_no_of_ways(
				        task_performed
				    )
				)





